From 74f2df56afed5b5519f1bab3247bb8f7e90e49c2 Mon Sep 17 00:00:00 2001
From: tempus2016
Date: Fri, 16 Oct 2026 21:41:13 +0000
Subject: [PATCH] docs: publish the documentation as a GitHub Pages site
Moves the GitHub wiki into wiki/ and builds it with MkDocs Material,
published to https://tempus2016.github.io/taskmate/ by a new Docs
workflow. Pull requests build in strict mode so broken links and
anchors fail before they reach the site.
The navigation follows the sections on the old wiki home page. Links
in the README, contributing guide, issue templates and the admin
panel's docs button now point at the new site, and the button's
tooltip says documentation rather than wiki in every locale.
---
.github/CONTRIBUTING.md | 2 +-
.github/ISSUE_TEMPLATE/bug_report.yml | 4 +-
.github/ISSUE_TEMPLATE/config.yml | 4 +-
.github/ISSUE_TEMPLATE/feature_request.yml | 2 +-
.github/workflows/docs.yml | 79 ++
.pre-commit-config.yaml | 5 +-
README.md | 44 +-
.../taskmate/www/locales/da.json | 2 +-
.../taskmate/www/locales/de.json | 2 +-
.../taskmate/www/locales/en-GB.json | 2 +-
.../taskmate/www/locales/en.json | 2 +-
.../taskmate/www/locales/fr.json | 2 +-
.../taskmate/www/locales/nb.json | 2 +-
.../taskmate/www/locales/nn.json | 2 +-
.../taskmate/www/locales/pl.json | 2 +-
.../taskmate/www/locales/pt-BR.json | 2 +-
.../taskmate/www/locales/pt.json | 2 +-
.../taskmate/www/taskmate-panel.js | 2 +-
mkdocs.yml | 163 +++
requirements-docs.txt | 4 +
wiki/Achievement-Badges.md | 391 ++++++
wiki/Admin-Audit-Log.md | 66 +
wiki/Admin-Panel.md | 314 +++++
wiki/Adult-Profiles.md | 88 ++
wiki/Allowance.md | 90 ++
wiki/Approvals-Card.md | 124 ++
wiki/Auto-Approve.md | 71 +
wiki/Automations.md | 637 +++++++++
wiki/Avatars.md | 115 ++
wiki/Backup-and-Restore.md | 78 ++
wiki/Birthday-Mode.md | 105 ++
wiki/Bonus-Points.md | 143 ++
wiki/Bonus-Subtasks.md | 114 ++
wiki/Bonuses.md | 190 +++
wiki/Bounty-Board.md | 134 ++
wiki/Calendar.md | 113 ++
wiki/Card-Design-Styles.md | 99 ++
wiki/Celebrations.md | 122 ++
wiki/Challenges.md | 112 ++
wiki/Child-Undo-Window.md | 86 ++
wiki/Children.md | 167 +++
wiki/Chore-Auctions.md | 117 ++
wiki/Chore-Dependencies.md | 78 ++
wiki/Chore-Roulette.md | 65 +
wiki/Chore-Scheduling.md | 293 +++++
wiki/Chore-Swaps.md | 87 ++
wiki/Chores.md | 414 ++++++
wiki/Completion-Sounds.md | 66 +
wiki/Configuration-Entities.md | 72 ++
wiki/Dashboard-Cards.md | 1033 +++++++++++++++
wiki/Difficulty-Tiers.md | 87 ++
wiki/Dynamic-Chore-Visibility.md | 227 ++++
wiki/Estimated-Minutes.md | 56 +
wiki/Event-Entities.md | 123 ++
wiki/External-Lock-Screen-Shops.md | 101 ++
wiki/FAQ.md | 149 +++
wiki/Family-Goals.md | 74 ++
wiki/Getting-Started.md | 150 +++
wiki/Gifting-Points.md | 64 +
wiki/Guest-Child-Profiles.md | 43 +
wiki/Help-Requests.md | 71 +
wiki/Insights.md | 103 ++
wiki/Installation.md | 138 ++
wiki/Kiosk-Mode.md | 249 ++++
wiki/Leaderboard-Seasons.md | 65 +
wiki/Levels-and-XP.md | 102 ++
wiki/Localization.md | 103 ++
wiki/Logging-Past-Jobs.md | 77 ++
wiki/Make-It-Right-Penalties.md | 91 ++
wiki/Managing-Rewards.md | 92 ++
wiki/Mandatory-Chores.md | 91 ++
wiki/Mood-Check-In.md | 83 ++
wiki/Multi-Parent-Approval-Routing.md | 50 +
wiki/NFC-Tag-Completion.md | 114 ++
wiki/Notifications.md | 590 +++++++++
wiki/Open-Ended-Chores.md | 115 ++
wiki/Parent-Access.md | 59 +
wiki/Penalties.md | 219 ++++
wiki/Photo-Proof.md | 98 ++
wiki/Points-Economy.md | 146 +++
wiki/Pool-Mode-(Savings-Jars).md | 116 ++
wiki/Pre-Reader-Mode.md | 67 +
wiki/Presence-Aware-Reminders.md | 83 ++
wiki/Printable-Weekly-Chart.md | 43 +
wiki/Quality-Ratings.md | 102 ++
wiki/Quantity-Chores.md | 96 ++
wiki/Quests.md | 106 ++
wiki/Quiet-Hours.md | 66 +
wiki/Raffles.md | 160 +++
wiki/Reactive-Chores.md | 76 ++
wiki/Read-Aloud.md | 78 ++
wiki/Ready-Made-Dashboards.md | 73 ++
wiki/Recaps.md | 96 ++
wiki/Reference-Photos.md | 60 +
wiki/Reject-Reasons.md | 93 ++
wiki/Reminder-Escalation.md | 64 +
wiki/Repairs-and-Diagnostics.md | 90 ++
wiki/Rewards.md | 139 ++
wiki/Routine-Mode.md | 77 ++
wiki/Scheduled-Config-Changes.md | 60 +
wiki/Sensor-Attributes.md | 255 ++++
wiki/Sensor-Reference.md | 751 +++++++++++
wiki/Services.md | 1151 +++++++++++++++++
wiki/Settings.md | 429 ++++++
wiki/Setup-Wizard.md | 115 ++
wiki/Sick-Days.md | 75 ++
wiki/Sticker-Chart-Card.md | 122 ++
wiki/Streak-Freezes.md | 111 ++
wiki/Surprise-Inspections.md | 99 ++
wiki/Task-Groups.md | 138 ++
wiki/Teamwork-Chores.md | 117 ++
wiki/Template-Packs.md | 45 +
wiki/Time-Locked-Rewards.md | 62 +
wiki/Timed-Tasks.md | 181 +++
wiki/Timed-Unlock-Rewards.md | 70 +
wiki/To-Do-Lists.md | 67 +
wiki/Troubleshooting.md | 329 +++++
wiki/Two-Way-Calendar.md | 93 ++
wiki/Vacation-Mode.md | 80 ++
wiki/Virtual-Pets.md | 199 +++
wiki/Visibility-Configuration-Guide.md | 547 ++++++++
wiki/Visibility-Operators-Reference.md | 470 +++++++
wiki/Voice-Assistants.md | 133 ++
wiki/Watch-Complications.md | 229 ++++
wiki/Weather-Aware-Chores.md | 74 ++
wiki/Weekly-Digest.md | 63 +
wiki/Weekly-Goals.md | 114 ++
wiki/Weekly-Targets.md | 119 ++
wiki/Wishlist.md | 123 ++
wiki/images/activity-undo.png | Bin 0 -> 119956 bytes
wiki/images/admin-chore-editor.png | Bin 0 -> 145877 bytes
wiki/images/admin-chore-kebab.png | Bin 0 -> 128711 bytes
wiki/images/admin-settings.png | Bin 0 -> 181500 bytes
wiki/images/adult-profile-card.png | Bin 0 -> 46735 bytes
wiki/images/adult-profile-dialog.png | Bin 0 -> 52038 bytes
wiki/images/approvals-mandatory.png | Bin 0 -> 109745 bytes
wiki/images/approvals-reference-photo.png | Bin 0 -> 85811 bytes
wiki/images/auction-card.png | Bin 0 -> 75823 bytes
wiki/images/birthday-card.png | Bin 0 -> 109094 bytes
wiki/images/bounty-card.png | Bin 0 -> 152710 bytes
wiki/images/calendar-card.png | Bin 0 -> 76269 bytes
wiki/images/card-activity.png | Bin 0 -> 136388 bytes
wiki/images/card-approvals.png | Bin 0 -> 56467 bytes
wiki/images/card-badges.png | Bin 0 -> 740112 bytes
wiki/images/card-bonuses.png | Bin 0 -> 80874 bytes
wiki/images/card-calendar.png | Bin 0 -> 119634 bytes
wiki/images/card-child-pre-reader.png | Bin 0 -> 107952 bytes
wiki/images/card-child.png | Bin 0 -> 176959 bytes
wiki/images/card-family-goal.png | Bin 0 -> 29371 bytes
wiki/images/card-graph.png | Bin 0 -> 58314 bytes
wiki/images/card-leaderboard.png | Bin 0 -> 195436 bytes
wiki/images/card-overview.png | Bin 0 -> 77153 bytes
wiki/images/card-parent-dashboard.png | Bin 0 -> 73165 bytes
wiki/images/card-penalties.png | Bin 0 -> 78852 bytes
wiki/images/card-photo-gallery.png | Bin 0 -> 39699 bytes
wiki/images/card-points-display.png | Bin 0 -> 73698 bytes
wiki/images/card-points.png | Bin 0 -> 77593 bytes
wiki/images/card-reorder.png | Bin 0 -> 175847 bytes
wiki/images/card-reward-progress.png | Bin 0 -> 92188 bytes
wiki/images/card-rewards.png | Bin 0 -> 578840 bytes
wiki/images/card-routine.png | Bin 0 -> 60952 bytes
wiki/images/card-streak.png | Bin 0 -> 150736 bytes
wiki/images/card-weekly.png | Bin 0 -> 81425 bytes
wiki/images/child-card-help-and-minutes.png | Bin 0 -> 186441 bytes
wiki/images/child-card-mandatory.png | Bin 0 -> 68475 bytes
wiki/images/child-kiosk-pin.png | Bin 0 -> 43106 bytes
wiki/images/child-undo-card.png | Bin 0 -> 270156 bytes
wiki/images/chore-board-card.png | Bin 0 -> 67739 bytes
wiki/images/chore-editor-minutes-quantity.png | Bin 0 -> 69110 bytes
wiki/images/chore-editor-reference-photo.png | Bin 0 -> 61601 bytes
wiki/images/dashboard-dialog-kids.png | Bin 0 -> 189686 bytes
wiki/images/dashboard-kids.png | Bin 0 -> 239800 bytes
wiki/images/design-styles.png | Bin 0 -> 278537 bytes
wiki/images/dev-tools-states.png | Bin 0 -> 458039 bytes
wiki/images/diagnostics-download.png | Bin 0 -> 121828 bytes
wiki/images/diagnostics-redacted.png | Bin 0 -> 285501 bytes
.../images/event-entity-automation-editor.png | Bin 0 -> 44132 bytes
wiki/images/event-entity-more-info.png | Bin 0 -> 122128 bytes
wiki/images/every-n-days-editor.png | Bin 0 -> 62815 bytes
wiki/images/ha-integration-entry.png | Bin 0 -> 148267 bytes
wiki/images/ha-todo-lists.png | Bin 0 -> 125456 bytes
wiki/images/insights-fairness.png | Bin 0 -> 124664 bytes
wiki/images/insights-friction.png | Bin 0 -> 211120 bytes
wiki/images/insights-health.png | Bin 0 -> 105647 bytes
wiki/images/insights-week-ahead.png | Bin 0 -> 151727 bytes
wiki/images/inspection-child-card.png | Bin 0 -> 41052 bytes
wiki/images/inspection-dialog.png | Bin 0 -> 75130 bytes
wiki/images/kiosk-bounties.png | Bin 0 -> 59411 bytes
wiki/images/kiosk-child.png | Bin 0 -> 169033 bytes
wiki/images/kiosk-picker.png | Bin 0 -> 92113 bytes
wiki/images/kiosk-pin.png | Bin 0 -> 91976 bytes
wiki/images/kiosk-raffle-draw.png | Bin 0 -> 80939 bytes
wiki/images/log-past-job-dialog.png | Bin 0 -> 129369 bytes
wiki/images/make-it-right-child-card.png | Bin 0 -> 192507 bytes
wiki/images/mood-check-in-child-card.png | Bin 0 -> 245256 bytes
wiki/images/nfc-tag-editor.png | Bin 0 -> 203651 bytes
wiki/images/open-ended-child-sheet.png | Bin 0 -> 126637 bytes
wiki/images/open-ended-review.png | Bin 0 -> 101495 bytes
wiki/images/panel-activity.png | Bin 0 -> 203305 bytes
wiki/images/panel-auctions.png | Bin 0 -> 240619 bytes
wiki/images/panel-audit-log.png | Bin 0 -> 225867 bytes
wiki/images/panel-badges.png | Bin 0 -> 227941 bytes
wiki/images/panel-bonuses.png | Bin 0 -> 88470 bytes
wiki/images/panel-bounties.png | Bin 0 -> 251939 bytes
wiki/images/panel-challenges.png | Bin 0 -> 101497 bytes
wiki/images/panel-child-filter.png | Bin 0 -> 358866 bytes
wiki/images/panel-children.png | Bin 0 -> 121460 bytes
wiki/images/panel-chore-editor.png | Bin 0 -> 443419 bytes
wiki/images/panel-chores.png | Bin 0 -> 176201 bytes
wiki/images/panel-command-search.png | Bin 0 -> 233818 bytes
.../panel-insights-fairness-minutes.png | Bin 0 -> 94859 bytes
wiki/images/panel-insights-moods.png | Bin 0 -> 95270 bytes
wiki/images/panel-notifications.png | Bin 0 -> 163495 bytes
wiki/images/panel-penalties.png | Bin 0 -> 87537 bytes
wiki/images/panel-quests.png | Bin 0 -> 125723 bytes
wiki/images/panel-raffle-dialog.png | Bin 0 -> 93575 bytes
wiki/images/panel-raffles.png | Bin 0 -> 115604 bytes
wiki/images/panel-ready-made-dashboards.png | Bin 0 -> 416618 bytes
wiki/images/panel-rewards-time-locked.png | Bin 0 -> 163943 bytes
wiki/images/panel-rewards.png | Bin 0 -> 107323 bytes
wiki/images/panel-settings-auto-approve.png | Bin 0 -> 35079 bytes
wiki/images/panel-settings-inspections.png | Bin 0 -> 421233 bytes
wiki/images/panel-settings-pets.png | Bin 0 -> 359647 bytes
wiki/images/panel-settings-recaps.png | Bin 0 -> 481207 bytes
wiki/images/panel-settings-sounds.png | Bin 0 -> 357795 bytes
wiki/images/panel-settings-weekly-goals.png | Bin 0 -> 45535 bytes
wiki/images/panel-settings-wizard.png | Bin 0 -> 208795 bytes
wiki/images/panel-settings.png | Bin 0 -> 186112 bytes
wiki/images/panel-task-groups.png | Bin 0 -> 95880 bytes
wiki/images/panel-templates.png | Bin 0 -> 125445 bytes
wiki/images/panel-today-help.png | Bin 0 -> 27745 bytes
wiki/images/panel-today-sick-and-mood.png | Bin 0 -> 44107 bytes
wiki/images/panel-today.png | Bin 0 -> 500263 bytes
wiki/images/panel-wishlists.png | Bin 0 -> 352276 bytes
wiki/images/penalty-make-it-right-editor.png | Bin 0 -> 103818 bytes
wiki/images/pet-adopt.png | Bin 0 -> 74551 bytes
wiki/images/pet-card.png | Bin 0 -> 593029 bytes
wiki/images/pet-stages.png | Bin 0 -> 387190 bytes
wiki/images/presence-child-dialog.png | Bin 0 -> 92983 bytes
wiki/images/printable-weekly-chart.png | Bin 0 -> 202122 bytes
wiki/images/quality-rating-approvals.png | Bin 0 -> 58587 bytes
wiki/images/quantity-chore-sheet.png | Bin 0 -> 37403 bytes
wiki/images/quantity-routine-stepper.png | Bin 0 -> 48745 bytes
wiki/images/raffle-card.png | Bin 0 -> 137028 bytes
wiki/images/raffle-draw-reveal.png | Bin 0 -> 36839 bytes
wiki/images/recap-card.png | Bin 0 -> 939531 bytes
wiki/images/reference-photo-compare.png | Bin 0 -> 173032 bytes
wiki/images/reference-photo-review-sheet.png | Bin 0 -> 83813 bytes
wiki/images/reject-reason-child-card.png | Bin 0 -> 177291 bytes
wiki/images/reject-reason-sheet.png | Bin 0 -> 48281 bytes
wiki/images/repairs-detail.png | Bin 0 -> 81046 bytes
wiki/images/repairs-list.png | Bin 0 -> 60628 bytes
wiki/images/reward-time-lock-editor.png | Bin 0 -> 202305 bytes
wiki/images/sick-day-child-card.png | Bin 0 -> 83253 bytes
wiki/images/sticker-chart-card.png | Bin 0 -> 435240 bytes
wiki/images/streak-freeze-card.png | Bin 0 -> 53717 bytes
wiki/images/teamwork-chore-card.png | Bin 0 -> 145309 bytes
wiki/images/two-way-calendar.png | Bin 0 -> 291513 bytes
wiki/images/watch-sensor-attributes.png | Bin 0 -> 95999 bytes
wiki/images/weekly-goal-card.png | Bin 0 -> 74359 bytes
wiki/images/weekly-goal-sheet.png | Bin 0 -> 41367 bytes
wiki/images/weekly-target-bonus-editor.png | Bin 0 -> 67671 bytes
wiki/images/weekly-target-card.png | Bin 0 -> 186325 bytes
wiki/images/wishlist-card.png | Bin 0 -> 118230 bytes
wiki/images/wizard-children.png | Bin 0 -> 456010 bytes
wiki/images/wizard-chores.png | Bin 0 -> 520976 bytes
wiki/images/wizard-dashboards.png | Bin 0 -> 332947 bytes
wiki/images/wizard-review.png | Bin 0 -> 324304 bytes
wiki/index.md | 209 +++
269 files changed, 17917 insertions(+), 41 deletions(-)
create mode 100644 .github/workflows/docs.yml
create mode 100644 mkdocs.yml
create mode 100644 requirements-docs.txt
create mode 100644 wiki/Achievement-Badges.md
create mode 100644 wiki/Admin-Audit-Log.md
create mode 100644 wiki/Admin-Panel.md
create mode 100644 wiki/Adult-Profiles.md
create mode 100644 wiki/Allowance.md
create mode 100644 wiki/Approvals-Card.md
create mode 100644 wiki/Auto-Approve.md
create mode 100644 wiki/Automations.md
create mode 100644 wiki/Avatars.md
create mode 100644 wiki/Backup-and-Restore.md
create mode 100644 wiki/Birthday-Mode.md
create mode 100644 wiki/Bonus-Points.md
create mode 100644 wiki/Bonus-Subtasks.md
create mode 100644 wiki/Bonuses.md
create mode 100644 wiki/Bounty-Board.md
create mode 100644 wiki/Calendar.md
create mode 100644 wiki/Card-Design-Styles.md
create mode 100644 wiki/Celebrations.md
create mode 100644 wiki/Challenges.md
create mode 100644 wiki/Child-Undo-Window.md
create mode 100644 wiki/Children.md
create mode 100644 wiki/Chore-Auctions.md
create mode 100644 wiki/Chore-Dependencies.md
create mode 100644 wiki/Chore-Roulette.md
create mode 100644 wiki/Chore-Scheduling.md
create mode 100644 wiki/Chore-Swaps.md
create mode 100644 wiki/Chores.md
create mode 100644 wiki/Completion-Sounds.md
create mode 100644 wiki/Configuration-Entities.md
create mode 100644 wiki/Dashboard-Cards.md
create mode 100644 wiki/Difficulty-Tiers.md
create mode 100644 wiki/Dynamic-Chore-Visibility.md
create mode 100644 wiki/Estimated-Minutes.md
create mode 100644 wiki/Event-Entities.md
create mode 100644 wiki/External-Lock-Screen-Shops.md
create mode 100644 wiki/FAQ.md
create mode 100644 wiki/Family-Goals.md
create mode 100644 wiki/Getting-Started.md
create mode 100644 wiki/Gifting-Points.md
create mode 100644 wiki/Guest-Child-Profiles.md
create mode 100644 wiki/Help-Requests.md
create mode 100644 wiki/Insights.md
create mode 100644 wiki/Installation.md
create mode 100644 wiki/Kiosk-Mode.md
create mode 100644 wiki/Leaderboard-Seasons.md
create mode 100644 wiki/Levels-and-XP.md
create mode 100644 wiki/Localization.md
create mode 100644 wiki/Logging-Past-Jobs.md
create mode 100644 wiki/Make-It-Right-Penalties.md
create mode 100644 wiki/Managing-Rewards.md
create mode 100644 wiki/Mandatory-Chores.md
create mode 100644 wiki/Mood-Check-In.md
create mode 100644 wiki/Multi-Parent-Approval-Routing.md
create mode 100644 wiki/NFC-Tag-Completion.md
create mode 100644 wiki/Notifications.md
create mode 100644 wiki/Open-Ended-Chores.md
create mode 100644 wiki/Parent-Access.md
create mode 100644 wiki/Penalties.md
create mode 100644 wiki/Photo-Proof.md
create mode 100644 wiki/Points-Economy.md
create mode 100644 wiki/Pool-Mode-(Savings-Jars).md
create mode 100644 wiki/Pre-Reader-Mode.md
create mode 100644 wiki/Presence-Aware-Reminders.md
create mode 100644 wiki/Printable-Weekly-Chart.md
create mode 100644 wiki/Quality-Ratings.md
create mode 100644 wiki/Quantity-Chores.md
create mode 100644 wiki/Quests.md
create mode 100644 wiki/Quiet-Hours.md
create mode 100644 wiki/Raffles.md
create mode 100644 wiki/Reactive-Chores.md
create mode 100644 wiki/Read-Aloud.md
create mode 100644 wiki/Ready-Made-Dashboards.md
create mode 100644 wiki/Recaps.md
create mode 100644 wiki/Reference-Photos.md
create mode 100644 wiki/Reject-Reasons.md
create mode 100644 wiki/Reminder-Escalation.md
create mode 100644 wiki/Repairs-and-Diagnostics.md
create mode 100644 wiki/Rewards.md
create mode 100644 wiki/Routine-Mode.md
create mode 100644 wiki/Scheduled-Config-Changes.md
create mode 100644 wiki/Sensor-Attributes.md
create mode 100644 wiki/Sensor-Reference.md
create mode 100644 wiki/Services.md
create mode 100644 wiki/Settings.md
create mode 100644 wiki/Setup-Wizard.md
create mode 100644 wiki/Sick-Days.md
create mode 100644 wiki/Sticker-Chart-Card.md
create mode 100644 wiki/Streak-Freezes.md
create mode 100644 wiki/Surprise-Inspections.md
create mode 100644 wiki/Task-Groups.md
create mode 100644 wiki/Teamwork-Chores.md
create mode 100644 wiki/Template-Packs.md
create mode 100644 wiki/Time-Locked-Rewards.md
create mode 100644 wiki/Timed-Tasks.md
create mode 100644 wiki/Timed-Unlock-Rewards.md
create mode 100644 wiki/To-Do-Lists.md
create mode 100644 wiki/Troubleshooting.md
create mode 100644 wiki/Two-Way-Calendar.md
create mode 100644 wiki/Vacation-Mode.md
create mode 100644 wiki/Virtual-Pets.md
create mode 100644 wiki/Visibility-Configuration-Guide.md
create mode 100644 wiki/Visibility-Operators-Reference.md
create mode 100644 wiki/Voice-Assistants.md
create mode 100644 wiki/Watch-Complications.md
create mode 100644 wiki/Weather-Aware-Chores.md
create mode 100644 wiki/Weekly-Digest.md
create mode 100644 wiki/Weekly-Goals.md
create mode 100644 wiki/Weekly-Targets.md
create mode 100644 wiki/Wishlist.md
create mode 100644 wiki/images/activity-undo.png
create mode 100644 wiki/images/admin-chore-editor.png
create mode 100644 wiki/images/admin-chore-kebab.png
create mode 100644 wiki/images/admin-settings.png
create mode 100644 wiki/images/adult-profile-card.png
create mode 100644 wiki/images/adult-profile-dialog.png
create mode 100644 wiki/images/approvals-mandatory.png
create mode 100644 wiki/images/approvals-reference-photo.png
create mode 100644 wiki/images/auction-card.png
create mode 100644 wiki/images/birthday-card.png
create mode 100644 wiki/images/bounty-card.png
create mode 100644 wiki/images/calendar-card.png
create mode 100644 wiki/images/card-activity.png
create mode 100644 wiki/images/card-approvals.png
create mode 100644 wiki/images/card-badges.png
create mode 100644 wiki/images/card-bonuses.png
create mode 100644 wiki/images/card-calendar.png
create mode 100644 wiki/images/card-child-pre-reader.png
create mode 100644 wiki/images/card-child.png
create mode 100644 wiki/images/card-family-goal.png
create mode 100644 wiki/images/card-graph.png
create mode 100644 wiki/images/card-leaderboard.png
create mode 100644 wiki/images/card-overview.png
create mode 100644 wiki/images/card-parent-dashboard.png
create mode 100644 wiki/images/card-penalties.png
create mode 100644 wiki/images/card-photo-gallery.png
create mode 100644 wiki/images/card-points-display.png
create mode 100644 wiki/images/card-points.png
create mode 100644 wiki/images/card-reorder.png
create mode 100644 wiki/images/card-reward-progress.png
create mode 100644 wiki/images/card-rewards.png
create mode 100644 wiki/images/card-routine.png
create mode 100644 wiki/images/card-streak.png
create mode 100644 wiki/images/card-weekly.png
create mode 100644 wiki/images/child-card-help-and-minutes.png
create mode 100644 wiki/images/child-card-mandatory.png
create mode 100644 wiki/images/child-kiosk-pin.png
create mode 100644 wiki/images/child-undo-card.png
create mode 100644 wiki/images/chore-board-card.png
create mode 100644 wiki/images/chore-editor-minutes-quantity.png
create mode 100644 wiki/images/chore-editor-reference-photo.png
create mode 100644 wiki/images/dashboard-dialog-kids.png
create mode 100644 wiki/images/dashboard-kids.png
create mode 100644 wiki/images/design-styles.png
create mode 100644 wiki/images/dev-tools-states.png
create mode 100644 wiki/images/diagnostics-download.png
create mode 100644 wiki/images/diagnostics-redacted.png
create mode 100644 wiki/images/event-entity-automation-editor.png
create mode 100644 wiki/images/event-entity-more-info.png
create mode 100644 wiki/images/every-n-days-editor.png
create mode 100644 wiki/images/ha-integration-entry.png
create mode 100644 wiki/images/ha-todo-lists.png
create mode 100644 wiki/images/insights-fairness.png
create mode 100644 wiki/images/insights-friction.png
create mode 100644 wiki/images/insights-health.png
create mode 100644 wiki/images/insights-week-ahead.png
create mode 100644 wiki/images/inspection-child-card.png
create mode 100644 wiki/images/inspection-dialog.png
create mode 100644 wiki/images/kiosk-bounties.png
create mode 100644 wiki/images/kiosk-child.png
create mode 100644 wiki/images/kiosk-picker.png
create mode 100644 wiki/images/kiosk-pin.png
create mode 100644 wiki/images/kiosk-raffle-draw.png
create mode 100644 wiki/images/log-past-job-dialog.png
create mode 100644 wiki/images/make-it-right-child-card.png
create mode 100644 wiki/images/mood-check-in-child-card.png
create mode 100644 wiki/images/nfc-tag-editor.png
create mode 100644 wiki/images/open-ended-child-sheet.png
create mode 100644 wiki/images/open-ended-review.png
create mode 100644 wiki/images/panel-activity.png
create mode 100644 wiki/images/panel-auctions.png
create mode 100644 wiki/images/panel-audit-log.png
create mode 100644 wiki/images/panel-badges.png
create mode 100644 wiki/images/panel-bonuses.png
create mode 100644 wiki/images/panel-bounties.png
create mode 100644 wiki/images/panel-challenges.png
create mode 100644 wiki/images/panel-child-filter.png
create mode 100644 wiki/images/panel-children.png
create mode 100644 wiki/images/panel-chore-editor.png
create mode 100644 wiki/images/panel-chores.png
create mode 100644 wiki/images/panel-command-search.png
create mode 100644 wiki/images/panel-insights-fairness-minutes.png
create mode 100644 wiki/images/panel-insights-moods.png
create mode 100644 wiki/images/panel-notifications.png
create mode 100644 wiki/images/panel-penalties.png
create mode 100644 wiki/images/panel-quests.png
create mode 100644 wiki/images/panel-raffle-dialog.png
create mode 100644 wiki/images/panel-raffles.png
create mode 100644 wiki/images/panel-ready-made-dashboards.png
create mode 100644 wiki/images/panel-rewards-time-locked.png
create mode 100644 wiki/images/panel-rewards.png
create mode 100644 wiki/images/panel-settings-auto-approve.png
create mode 100644 wiki/images/panel-settings-inspections.png
create mode 100644 wiki/images/panel-settings-pets.png
create mode 100644 wiki/images/panel-settings-recaps.png
create mode 100644 wiki/images/panel-settings-sounds.png
create mode 100644 wiki/images/panel-settings-weekly-goals.png
create mode 100644 wiki/images/panel-settings-wizard.png
create mode 100644 wiki/images/panel-settings.png
create mode 100644 wiki/images/panel-task-groups.png
create mode 100644 wiki/images/panel-templates.png
create mode 100644 wiki/images/panel-today-help.png
create mode 100644 wiki/images/panel-today-sick-and-mood.png
create mode 100644 wiki/images/panel-today.png
create mode 100644 wiki/images/panel-wishlists.png
create mode 100644 wiki/images/penalty-make-it-right-editor.png
create mode 100644 wiki/images/pet-adopt.png
create mode 100644 wiki/images/pet-card.png
create mode 100644 wiki/images/pet-stages.png
create mode 100644 wiki/images/presence-child-dialog.png
create mode 100644 wiki/images/printable-weekly-chart.png
create mode 100644 wiki/images/quality-rating-approvals.png
create mode 100644 wiki/images/quantity-chore-sheet.png
create mode 100644 wiki/images/quantity-routine-stepper.png
create mode 100644 wiki/images/raffle-card.png
create mode 100644 wiki/images/raffle-draw-reveal.png
create mode 100644 wiki/images/recap-card.png
create mode 100644 wiki/images/reference-photo-compare.png
create mode 100644 wiki/images/reference-photo-review-sheet.png
create mode 100644 wiki/images/reject-reason-child-card.png
create mode 100644 wiki/images/reject-reason-sheet.png
create mode 100644 wiki/images/repairs-detail.png
create mode 100644 wiki/images/repairs-list.png
create mode 100644 wiki/images/reward-time-lock-editor.png
create mode 100644 wiki/images/sick-day-child-card.png
create mode 100644 wiki/images/sticker-chart-card.png
create mode 100644 wiki/images/streak-freeze-card.png
create mode 100644 wiki/images/teamwork-chore-card.png
create mode 100644 wiki/images/two-way-calendar.png
create mode 100644 wiki/images/watch-sensor-attributes.png
create mode 100644 wiki/images/weekly-goal-card.png
create mode 100644 wiki/images/weekly-goal-sheet.png
create mode 100644 wiki/images/weekly-target-bonus-editor.png
create mode 100644 wiki/images/weekly-target-card.png
create mode 100644 wiki/images/wishlist-card.png
create mode 100644 wiki/images/wizard-children.png
create mode 100644 wiki/images/wizard-chores.png
create mode 100644 wiki/images/wizard-dashboards.png
create mode 100644 wiki/images/wizard-review.png
create mode 100644 wiki/index.md
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index 96240662..6c2d3b4c 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -13,7 +13,7 @@ welcome — bug reports, feature ideas, translations, docs, and code.
- **Questions and ideas:** use
[Discussions](https://github.com/tempus2016/taskmate/discussions) rather than
an issue.
-- **Check the [Troubleshooting wiki](https://github.com/tempus2016/taskmate/wiki/Troubleshooting)**
+- **Check the [Troubleshooting guide](https://tempus2016.github.io/taskmate/Troubleshooting/)**
first for common problems.
## Project layout
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index ef18eb0e..050af5ed 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -11,7 +11,7 @@ body:
value: |
Thanks for taking the time to report a bug. Please fill in as much detail as possible — it helps fix issues faster.
- Before submitting, please check the [Troubleshooting wiki page](https://github.com/tempus2016/taskmate/wiki/Troubleshooting) and [existing issues](https://github.com/tempus2016/taskmate/issues) to see if your issue is already covered.
+ Before submitting, please check the [Troubleshooting guide](https://tempus2016.github.io/taskmate/Troubleshooting/) and [existing issues](https://github.com/tempus2016/taskmate/issues) to see if your issue is already covered.
# ── Environment ──────────────────────────────────────────────────────────────
@@ -231,7 +231,7 @@ body:
attributes:
label: Before Submitting
options:
- - label: I have checked the [Troubleshooting wiki](https://github.com/tempus2016/taskmate/wiki/Troubleshooting) and my issue is not covered there
+ - label: I have checked the [Troubleshooting guide](https://tempus2016.github.io/taskmate/Troubleshooting/) and my issue is not covered there
required: true
- label: I have searched [existing issues](https://github.com/tempus2016/taskmate/issues) and this is not a duplicate
required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index cba6ec3a..a77334f7 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,7 +1,7 @@
blank_issues_enabled: false
contact_links:
- - name: 📖 Troubleshooting Wiki
- url: https://github.com/tempus2016/taskmate/wiki/Troubleshooting
+ - name: 📖 Troubleshooting guide
+ url: https://tempus2016.github.io/taskmate/Troubleshooting/
about: Check here first — most common issues are covered
- name: 💬 Discussions
url: https://github.com/tempus2016/taskmate/discussions
diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml
index a092421a..460780d0 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.yml
+++ b/.github/ISSUE_TEMPLATE/feature_request.yml
@@ -144,5 +144,5 @@ body:
options:
- label: I have searched [existing issues](https://github.com/tempus2016/taskmate/issues) and this has not already been requested
required: true
- - label: I have checked the [wiki](https://github.com/tempus2016/taskmate/wiki) and this feature doesn't already exist
+ - label: I have checked the [documentation](https://tempus2016.github.io/taskmate/) and this feature doesn't already exist
required: true
diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml
new file mode 100644
index 00000000..bc74f810
--- /dev/null
+++ b/.github/workflows/docs.yml
@@ -0,0 +1,79 @@
+name: Docs
+
+# Builds the documentation site from wiki/ with MkDocs Material and publishes
+# it to GitHub Pages (https://tempus2016.github.io/taskmate/).
+#
+# Pull requests only build, in strict mode, so a broken internal link or a
+# missing image fails here instead of on the live site. Pushes to main build
+# and deploy.
+
+on:
+ push:
+ branches: [main]
+ paths:
+ - "wiki/**"
+ - "mkdocs.yml"
+ - "requirements-docs.txt"
+ - ".github/workflows/docs.yml"
+ pull_request:
+ branches: [main]
+ paths:
+ - "wiki/**"
+ - "mkdocs.yml"
+ - "requirements-docs.txt"
+ - ".github/workflows/docs.yml"
+ workflow_dispatch:
+
+concurrency:
+ group: ${{ github.workflow }}-${{ github.ref }}
+ cancel-in-progress: true
+
+permissions:
+ contents: read
+
+jobs:
+ build:
+ name: Build docs
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Check out repository
+ uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+ with:
+ persist-credentials: false
+
+ - name: Set up Python
+ uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
+ with:
+ python-version: "3.14"
+
+ - name: Install MkDocs
+ run: python -m pip install -r requirements-docs.txt
+
+ - name: Build site
+ run: python -m mkdocs build --strict --site-dir site
+
+ - name: Upload Pages artifact
+ if: github.event_name != 'pull_request'
+ uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5.0.0
+ with:
+ path: site
+
+ deploy:
+ name: Deploy to GitHub Pages
+ if: github.event_name != 'pull_request'
+ needs: build
+ runs-on: ubuntu-latest
+
+ permissions:
+ pages: write
+ id-token: write
+
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+
+ steps:
+ - name: Deploy
+ id: deployment
+ uses: actions/deploy-pages@368f82528645a54fb793d4d04e342629a3f51346 # v5.0.1
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 11a72005..8976d0d8 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -25,8 +25,9 @@ repos:
- id: end-of-file-fixer
- id: check-json
- id: check-yaml
- # Blueprints use HA's !input tag, which plain YAML can't resolve.
- exclude: ^blueprints/
+ # Blueprints use HA's !input tag and mkdocs.yml a !!python tag for its
+ # heading slugs; plain YAML can resolve neither.
+ exclude: ^(blueprints/|mkdocs\.yml$)
- id: check-merge-conflict
- id: check-case-conflict
- id: check-added-large-files
diff --git a/README.md b/README.md
index 8b790b4f..89ff5863 100755
--- a/README.md
+++ b/README.md
@@ -28,7 +28,7 @@
- 📖 Full documentation lives in the Wiki .
+ 📖 Full documentation lives at tempus2016.github.io/taskmate .
---
@@ -65,21 +65,21 @@ TaskMate is a **default HACS integration** — no custom repository needed.
Requires **Home Assistant 2024.7+** and a current browser (Chrome, Firefox, Edge, or Safari).
-For manual installation and the first-run walkthrough, see [Installation](https://github.com/tempus2016/taskmate/wiki/Installation) and [Getting Started](https://github.com/tempus2016/taskmate/wiki/Getting-Started).
+For manual installation and the first-run walkthrough, see [Installation](https://tempus2016.github.io/taskmate/Installation/) and [Getting Started](https://tempus2016.github.io/taskmate/Getting-Started/).
---
## What you get
-**Chores** — flexible [scheduling](https://github.com/tempus2016/taskmate/wiki/Chore-Scheduling) (specific days, recurring down to every N days, rotation, first-come), [difficulty tiers](https://github.com/tempus2016/taskmate/wiki/Difficulty-Tiers), [dependencies](https://github.com/tempus2016/taskmate/wiki/Chore-Dependencies), [timed tasks](https://github.com/tempus2016/taskmate/wiki/Timed-Tasks), [weekly targets](https://github.com/tempus2016/taskmate/wiki/Weekly-Targets) for "three times this week, any day" with an optional bonus for hitting them, [photo proof](https://github.com/tempus2016/taskmate/wiki/Photo-Proof), [open-ended chores](https://github.com/tempus2016/taskmate/wiki/Open-Ended-Chores) the child describes and you price at approval, [teamwork chores](https://github.com/tempus2016/taskmate/wiki/Teamwork-Chores) that need two or more children, [chore auctions](https://github.com/tempus2016/taskmate/wiki/Chore-Auctions) where the lowest bid wins an unpopular job, a [bounty board](https://github.com/tempus2016/taskmate/wiki/Bounty-Board) of one-off jobs any child can claim, [swaps](https://github.com/tempus2016/taskmate/wiki/Chore-Swaps), [vacation mode](https://github.com/tempus2016/taskmate/wiki/Vacation-Mode), and chores that appear or hide based on [HA entity state](https://github.com/tempus2016/taskmate/wiki/Dynamic-Chore-Visibility) or [the weather](https://github.com/tempus2016/taskmate/wiki/Weather-Aware-Chores). Children can [tap an NFC tag](https://github.com/tempus2016/taskmate/wiki/NFC-Tag-Completion) to tick a chore off, and you can add, move and skip chores straight from [Home Assistant's calendar](https://github.com/tempus2016/taskmate/wiki/Two-Way-Calendar). Missed ticking one? [Log a past job](https://github.com/tempus2016/taskmate/wiki/Logging-Past-Jobs) on the day it was really done, up to a week back. Chores can carry an [estimated time](https://github.com/tempus2016/taskmate/wiki/Estimated-Minutes) so children see how long is left, a [reference photo](https://github.com/tempus2016/taskmate/wiki/Reference-Photos) of the job done well, or a [quantity](https://github.com/tempus2016/taskmate/wiki/Quantity-Chores) that pays per item, and pending chores can [approve themselves](https://github.com/tempus2016/taskmate/wiki/Auto-Approve) after a set number of hours.
+**Chores** — flexible [scheduling](https://tempus2016.github.io/taskmate/Chore-Scheduling/) (specific days, recurring down to every N days, rotation, first-come), [difficulty tiers](https://tempus2016.github.io/taskmate/Difficulty-Tiers/), [dependencies](https://tempus2016.github.io/taskmate/Chore-Dependencies/), [timed tasks](https://tempus2016.github.io/taskmate/Timed-Tasks/), [weekly targets](https://tempus2016.github.io/taskmate/Weekly-Targets/) for "three times this week, any day" with an optional bonus for hitting them, [photo proof](https://tempus2016.github.io/taskmate/Photo-Proof/), [open-ended chores](https://tempus2016.github.io/taskmate/Open-Ended-Chores/) the child describes and you price at approval, [teamwork chores](https://tempus2016.github.io/taskmate/Teamwork-Chores/) that need two or more children, [chore auctions](https://tempus2016.github.io/taskmate/Chore-Auctions/) where the lowest bid wins an unpopular job, a [bounty board](https://tempus2016.github.io/taskmate/Bounty-Board/) of one-off jobs any child can claim, [swaps](https://tempus2016.github.io/taskmate/Chore-Swaps/), [vacation mode](https://tempus2016.github.io/taskmate/Vacation-Mode/), and chores that appear or hide based on [HA entity state](https://tempus2016.github.io/taskmate/Dynamic-Chore-Visibility/) or [the weather](https://tempus2016.github.io/taskmate/Weather-Aware-Chores/). Children can [tap an NFC tag](https://tempus2016.github.io/taskmate/NFC-Tag-Completion/) to tick a chore off, and you can add, move and skip chores straight from [Home Assistant's calendar](https://tempus2016.github.io/taskmate/Two-Way-Calendar/). Missed ticking one? [Log a past job](https://tempus2016.github.io/taskmate/Logging-Past-Jobs/) on the day it was really done, up to a week back. Chores can carry an [estimated time](https://tempus2016.github.io/taskmate/Estimated-Minutes/) so children see how long is left, a [reference photo](https://tempus2016.github.io/taskmate/Reference-Photos/) of the job done well, or a [quantity](https://tempus2016.github.io/taskmate/Quantity-Chores/) that pays per item, and pending chores can [approve themselves](https://tempus2016.github.io/taskmate/Auto-Approve/) after a set number of hours.
-**Points & rewards** — [fixed-cost rewards](https://github.com/tempus2016/taskmate/wiki/Rewards) with a parent approval flow, [savings jars](https://github.com/tempus2016/taskmate/wiki/Pool-Mode-\(Savings-Jars\)), a [wishlist](https://github.com/tempus2016/taskmate/wiki/Wishlist) children save towards and family can pledge to, [bonuses](https://github.com/tempus2016/taskmate/wiki/Bonuses) and [penalties](https://github.com/tempus2016/taskmate/wiki/Penalties), [weekend multipliers and streak milestones](https://github.com/tempus2016/taskmate/wiki/Bonus-Points), [1–3 star quality ratings](https://github.com/tempus2016/taskmate/wiki/Quality-Ratings) that scale the points, [real-money allowance](https://github.com/tempus2016/taskmate/wiki/Allowance), [shared family goals](https://github.com/tempus2016/taskmate/wiki/Family-Goals), [timed device unlocks](https://github.com/tempus2016/taskmate/wiki/Timed-Unlock-Rewards), and [time-locked rewards](https://github.com/tempus2016/taskmate/wiki/Time-Locked-Rewards) that are only claimable on chosen days or between set hours. Children can buy tickets for a [raffle](https://github.com/tempus2016/taskmate/wiki/Raffles) with their points, and a [make-it-right penalty](https://github.com/tempus2016/taskmate/wiki/Make-It-Right-Penalties) can be earned back by doing a chore.
+**Points & rewards** — [fixed-cost rewards](https://tempus2016.github.io/taskmate/Rewards/) with a parent approval flow, [savings jars](https://tempus2016.github.io/taskmate/Pool-Mode-\(Savings-Jars\)/), a [wishlist](https://tempus2016.github.io/taskmate/Wishlist/) children save towards and family can pledge to, [bonuses](https://tempus2016.github.io/taskmate/Bonuses/) and [penalties](https://tempus2016.github.io/taskmate/Penalties/), [weekend multipliers and streak milestones](https://tempus2016.github.io/taskmate/Bonus-Points/), [1–3 star quality ratings](https://tempus2016.github.io/taskmate/Quality-Ratings/) that scale the points, [real-money allowance](https://tempus2016.github.io/taskmate/Allowance/), [shared family goals](https://tempus2016.github.io/taskmate/Family-Goals/), [timed device unlocks](https://tempus2016.github.io/taskmate/Timed-Unlock-Rewards/), and [time-locked rewards](https://tempus2016.github.io/taskmate/Time-Locked-Rewards/) that are only claimable on chosen days or between set hours. Children can buy tickets for a [raffle](https://tempus2016.github.io/taskmate/Raffles/) with their points, and a [make-it-right penalty](https://tempus2016.github.io/taskmate/Make-It-Right-Penalties/) can be earned back by doing a chore.
-**Gamification** — a [virtual pet](https://github.com/tempus2016/taskmate/wiki/Virtual-Pets) that hatches and grows as chores get done, [personal weekly goals](https://github.com/tempus2016/taskmate/wiki/Weekly-Goals) with a bonus, [levels & XP](https://github.com/tempus2016/taskmate/wiki/Levels-and-XP), [achievement badges](https://github.com/tempus2016/taskmate/wiki/Achievement-Badges), [quests](https://github.com/tempus2016/taskmate/wiki/Quests), [challenges](https://github.com/tempus2016/taskmate/wiki/Challenges), [unlockable avatars](https://github.com/tempus2016/taskmate/wiki/Avatars), [celebrations](https://github.com/tempus2016/taskmate/wiki/Celebrations), [leaderboard seasons](https://github.com/tempus2016/taskmate/wiki/Leaderboard-Seasons), [streak freezes](https://github.com/tempus2016/taskmate/wiki/Streak-Freezes) that protect a streak through a missed day, [birthday mode](https://github.com/tempus2016/taskmate/wiki/Birthday-Mode), [surprise inspections](https://github.com/tempus2016/taskmate/wiki/Surprise-Inspections) with a bonus, and "Wrapped"-style [recaps](https://github.com/tempus2016/taskmate/wiki/Recaps) on a schedule you choose.
+**Gamification** — a [virtual pet](https://tempus2016.github.io/taskmate/Virtual-Pets/) that hatches and grows as chores get done, [personal weekly goals](https://tempus2016.github.io/taskmate/Weekly-Goals/) with a bonus, [levels & XP](https://tempus2016.github.io/taskmate/Levels-and-XP/), [achievement badges](https://tempus2016.github.io/taskmate/Achievement-Badges/), [quests](https://tempus2016.github.io/taskmate/Quests/), [challenges](https://tempus2016.github.io/taskmate/Challenges/), [unlockable avatars](https://tempus2016.github.io/taskmate/Avatars/), [celebrations](https://tempus2016.github.io/taskmate/Celebrations/), [leaderboard seasons](https://tempus2016.github.io/taskmate/Leaderboard-Seasons/), [streak freezes](https://tempus2016.github.io/taskmate/Streak-Freezes/) that protect a streak through a missed day, [birthday mode](https://tempus2016.github.io/taskmate/Birthday-Mode/), [surprise inspections](https://tempus2016.github.io/taskmate/Surprise-Inspections/) with a bonus, and "Wrapped"-style [recaps](https://tempus2016.github.io/taskmate/Recaps/) on a schedule you choose.
-**Parent tooling** — an [admin panel](https://github.com/tempus2016/taskmate/wiki/Admin-Panel) with a Today home page and a [setup wizard](https://github.com/tempus2016/taskmate/wiki/Setup-Wizard) that suggests chores by age, [ready-made dashboards](https://github.com/tempus2016/taskmate/wiki/Ready-Made-Dashboards) for the kids, the parents and a wall tablet, [notifications](https://github.com/tempus2016/taskmate/wiki/Notifications) in your Home Assistant language, with [quiet hours](https://github.com/tempus2016/taskmate/wiki/Quiet-Hours), [reminder escalation](https://github.com/tempus2016/taskmate/wiki/Reminder-Escalation) and [presence-aware reminders](https://github.com/tempus2016/taskmate/wiki/Presence-Aware-Reminders) that wait until a child is home, [reject reasons](https://github.com/tempus2016/taskmate/wiki/Reject-Reasons) the child can see, [multi-parent approval routing](https://github.com/tempus2016/taskmate/wiki/Multi-Parent-Approval-Routing), a [weekly digest](https://github.com/tempus2016/taskmate/wiki/Weekly-Digest), [insight reports](https://github.com/tempus2016/taskmate/wiki/Insights) on fairness and friction, an [audit log](https://github.com/tempus2016/taskmate/wiki/Admin-Audit-Log), [sick days](https://github.com/tempus2016/taskmate/wiki/Sick-Days) that pause chores and protect streaks, [event entities](https://github.com/tempus2016/taskmate/wiki/Event-Entities) for building automations in the UI editor, [Repairs issues and a diagnostics download](https://github.com/tempus2016/taskmate/wiki/Repairs-and-Diagnostics), [adult profiles](https://github.com/tempus2016/taskmate/wiki/Adult-Profiles) so parents can track their own chores without approving each other's, and [backup & restore](https://github.com/tempus2016/taskmate/wiki/Backup-and-Restore).
+**Parent tooling** — an [admin panel](https://tempus2016.github.io/taskmate/Admin-Panel/) with a Today home page and a [setup wizard](https://tempus2016.github.io/taskmate/Setup-Wizard/) that suggests chores by age, [ready-made dashboards](https://tempus2016.github.io/taskmate/Ready-Made-Dashboards/) for the kids, the parents and a wall tablet, [notifications](https://tempus2016.github.io/taskmate/Notifications/) in your Home Assistant language, with [quiet hours](https://tempus2016.github.io/taskmate/Quiet-Hours/), [reminder escalation](https://tempus2016.github.io/taskmate/Reminder-Escalation/) and [presence-aware reminders](https://tempus2016.github.io/taskmate/Presence-Aware-Reminders/) that wait until a child is home, [reject reasons](https://tempus2016.github.io/taskmate/Reject-Reasons/) the child can see, [multi-parent approval routing](https://tempus2016.github.io/taskmate/Multi-Parent-Approval-Routing/), a [weekly digest](https://tempus2016.github.io/taskmate/Weekly-Digest/), [insight reports](https://tempus2016.github.io/taskmate/Insights/) on fairness and friction, an [audit log](https://tempus2016.github.io/taskmate/Admin-Audit-Log/), [sick days](https://tempus2016.github.io/taskmate/Sick-Days/) that pause chores and protect streaks, [event entities](https://tempus2016.github.io/taskmate/Event-Entities/) for building automations in the UI editor, [Repairs issues and a diagnostics download](https://tempus2016.github.io/taskmate/Repairs-and-Diagnostics/), [adult profiles](https://tempus2016.github.io/taskmate/Adult-Profiles/) so parents can track their own chores without approving each other's, and [backup & restore](https://tempus2016.github.io/taskmate/Backup-and-Restore/).
-**Made for kids** — a [sticker chart](https://github.com/tempus2016/taskmate/wiki/Sticker-Chart-Card) where today's jobs are stickers to tap and stars fill up towards a reward, [Routine Mode](https://github.com/tempus2016/taskmate/wiki/Routine-Mode) for guided morning and bedtime flows, [Pre-Reader Mode](https://github.com/tempus2016/taskmate/wiki/Pre-Reader-Mode) for children who can't read yet, [Kiosk Mode](https://github.com/tempus2016/taskmate/wiki/Kiosk-Mode) for a shared wall tablet (where they can claim bounties too, hide what's already done, and show the family's day or a photo slideshow while idle), a [child undo window](https://github.com/tempus2016/taskmate/wiki/Child-Undo-Window) so they can take back a mistaken tap, an ["I'm stuck" button](https://github.com/tempus2016/taskmate/wiki/Help-Requests) that asks a parent for help, an end-of-day [mood check-in](https://github.com/tempus2016/taskmate/wiki/Mood-Check-In), [watch complications](https://github.com/tempus2016/taskmate/wiki/Watch-Complications) for Apple Watch and Wear OS, [Read Aloud](https://github.com/tempus2016/taskmate/wiki/Read-Aloud) to a media player, a [printable fridge chart](https://github.com/tempus2016/taskmate/wiki/Printable-Weekly-Chart), each child's [photo](https://github.com/tempus2016/taskmate/wiki/Children#child-photos) on the cards from their Home Assistant person, [custom completion sounds](https://github.com/tempus2016/taskmate/wiki/Completion-Sounds) you can upload and pick per chore, and six [card design styles](https://github.com/tempus2016/taskmate/wiki/Card-Design-Styles) including a high-contrast accessible theme and a clean corporate one. Cards and the panel are translated into 10 languages and support [right-to-left layouts](https://github.com/tempus2016/taskmate/wiki/Localization).
+**Made for kids** — a [sticker chart](https://tempus2016.github.io/taskmate/Sticker-Chart-Card/) where today's jobs are stickers to tap and stars fill up towards a reward, [Routine Mode](https://tempus2016.github.io/taskmate/Routine-Mode/) for guided morning and bedtime flows, [Pre-Reader Mode](https://tempus2016.github.io/taskmate/Pre-Reader-Mode/) for children who can't read yet, [Kiosk Mode](https://tempus2016.github.io/taskmate/Kiosk-Mode/) for a shared wall tablet (where they can claim bounties too, hide what's already done, and show the family's day or a photo slideshow while idle), a [child undo window](https://tempus2016.github.io/taskmate/Child-Undo-Window/) so they can take back a mistaken tap, an ["I'm stuck" button](https://tempus2016.github.io/taskmate/Help-Requests/) that asks a parent for help, an end-of-day [mood check-in](https://tempus2016.github.io/taskmate/Mood-Check-In/), [watch complications](https://tempus2016.github.io/taskmate/Watch-Complications/) for Apple Watch and Wear OS, [Read Aloud](https://tempus2016.github.io/taskmate/Read-Aloud/) to a media player, a [printable fridge chart](https://tempus2016.github.io/taskmate/Printable-Weekly-Chart/), each child's [photo](https://tempus2016.github.io/taskmate/Children/#child-photos) on the cards from their Home Assistant person, [custom completion sounds](https://tempus2016.github.io/taskmate/Completion-Sounds/) you can upload and pick per chore, and six [card design styles](https://tempus2016.github.io/taskmate/Card-Design-Styles/) including a high-contrast accessible theme and a clean corporate one. Cards and the panel are translated into 10 languages and support [right-to-left layouts](https://tempus2016.github.io/taskmate/Localization/).
---
@@ -91,7 +91,7 @@ Lovelace resources register automatically on startup. Edit your dashboard → **
|----------|-------------|
| Child · Sticker Chart · Pet · Raffle · Rewards · Reward Progress · Points Display · Routine · Kiosk · Streak · Badges · Bounty Board · Wishlist · Recap · Chore Auction | Approvals · Parent Dashboard · Overview · Chore Board · Activity · Points · Reorder · Penalties · Bonuses · Weekly · Graph · Leaderboard · Calendar · Family Goal · Photo Gallery |
-Every card takes a `header_color` and a `card_design` option. See [Dashboard Cards](https://github.com/tempus2016/taskmate/wiki/Dashboard-Cards) for each card's full configuration.
+Every card takes a `header_color` and a `card_design` option. See [Dashboard Cards](https://tempus2016.github.io/taskmate/Dashboard-Cards/) for each card's full configuration.
@@ -105,20 +105,20 @@ Every card takes a `header_color` and a `card_design` option. See [Dashboard Car
| | |
|---|---|
-| [Getting Started](https://github.com/tempus2016/taskmate/wiki/Getting-Started) | First-time setup walkthrough |
-| [Admin Panel](https://github.com/tempus2016/taskmate/wiki/Admin-Panel) | The management hub in the HA sidebar |
-| [Settings](https://github.com/tempus2016/taskmate/wiki/Settings) | Every configurable setting in one place |
-| [Dashboard Cards](https://github.com/tempus2016/taskmate/wiki/Dashboard-Cards) | All 30 Lovelace cards and their options |
-| [Services](https://github.com/tempus2016/taskmate/wiki/Services) | Every callable service, with examples |
-| [Sensor Reference](https://github.com/tempus2016/taskmate/wiki/Sensor-Reference) | All entities and their attributes |
-| [Automations](https://github.com/tempus2016/taskmate/wiki/Automations) | Bus events, blueprints, and examples |
-| [Voice Assistants](https://github.com/tempus2016/taskmate/wiki/Voice-Assistants) | Ask Assist about chores and points |
-| [Watch Complications](https://github.com/tempus2016/taskmate/wiki/Watch-Complications) | TaskMate on Apple Watch and Wear OS |
-| [Localization](https://github.com/tempus2016/taskmate/wiki/Localization) | Supported languages and translating |
-| [Troubleshooting](https://github.com/tempus2016/taskmate/wiki/Troubleshooting) | Common issues and fixes |
-| [FAQ](https://github.com/tempus2016/taskmate/wiki/FAQ) | Frequently asked questions |
-
-**[→ Browse the full wiki](https://github.com/tempus2016/taskmate/wiki)** — 70+ pages, one per feature.
+| [Getting Started](https://tempus2016.github.io/taskmate/Getting-Started/) | First-time setup walkthrough |
+| [Admin Panel](https://tempus2016.github.io/taskmate/Admin-Panel/) | The management hub in the HA sidebar |
+| [Settings](https://tempus2016.github.io/taskmate/Settings/) | Every configurable setting in one place |
+| [Dashboard Cards](https://tempus2016.github.io/taskmate/Dashboard-Cards/) | All 30 Lovelace cards and their options |
+| [Services](https://tempus2016.github.io/taskmate/Services/) | Every callable service, with examples |
+| [Sensor Reference](https://tempus2016.github.io/taskmate/Sensor-Reference/) | All entities and their attributes |
+| [Automations](https://tempus2016.github.io/taskmate/Automations/) | Bus events, blueprints, and examples |
+| [Voice Assistants](https://tempus2016.github.io/taskmate/Voice-Assistants/) | Ask Assist about chores and points |
+| [Watch Complications](https://tempus2016.github.io/taskmate/Watch-Complications/) | TaskMate on Apple Watch and Wear OS |
+| [Localization](https://tempus2016.github.io/taskmate/Localization/) | Supported languages and translating |
+| [Troubleshooting](https://tempus2016.github.io/taskmate/Troubleshooting/) | Common issues and fixes |
+| [FAQ](https://tempus2016.github.io/taskmate/FAQ/) | Frequently asked questions |
+
+**[→ Browse the full documentation](https://tempus2016.github.io/taskmate/)** — 100+ pages, one per feature, with search.
---
diff --git a/custom_components/taskmate/www/locales/da.json b/custom_components/taskmate/www/locales/da.json
index 40b8f3fd..ea5205d8 100644
--- a/custom_components/taskmate/www/locales/da.json
+++ b/custom_components/taskmate/www/locales/da.json
@@ -1560,7 +1560,7 @@
"panel.tab_templates": "Skabeloner",
"panel.tab_today": "I dag",
"panel.tab_unknown": "Ukendt fane",
- "panel.wiki_tooltip": "Åbn TaskMate-wikien",
+ "panel.wiki_tooltip": "Åbn TaskMate-dokumentationen",
"panel.notif_add_custom": "Tilføj egen notifikation",
"panel.notif_add_parent": "Tilføj forælder",
"panel.notif_custom_empty": "Ingen egne notifikationer endnu.",
diff --git a/custom_components/taskmate/www/locales/de.json b/custom_components/taskmate/www/locales/de.json
index 0e3b2ffb..17bd7fbd 100644
--- a/custom_components/taskmate/www/locales/de.json
+++ b/custom_components/taskmate/www/locales/de.json
@@ -1496,7 +1496,7 @@
"panel.tab_templates": "Vorlagen",
"panel.tab_today": "Heute",
"panel.tab_unknown": "Unbekannter Tab",
- "panel.wiki_tooltip": "TaskMate-Wiki öffnen",
+ "panel.wiki_tooltip": "TaskMate-Dokumentation öffnen",
"panel.notif_add_custom": "Benutzerdefinierte Benachrichtigung hinzufügen",
"panel.notif_add_parent": "Elternteil hinzufügen",
"panel.notif_custom_empty": "Noch keine benutzerdefinierten Benachrichtigungen.",
diff --git a/custom_components/taskmate/www/locales/en-GB.json b/custom_components/taskmate/www/locales/en-GB.json
index 93b9e314..dda6fda4 100644
--- a/custom_components/taskmate/www/locales/en-GB.json
+++ b/custom_components/taskmate/www/locales/en-GB.json
@@ -1560,7 +1560,7 @@
"panel.tab_templates": "Templates",
"panel.tab_today": "Today",
"panel.tab_unknown": "Unknown tab",
- "panel.wiki_tooltip": "Open the TaskMate wiki",
+ "panel.wiki_tooltip": "Open the TaskMate documentation",
"panel.notif_add_custom": "Add custom notification",
"panel.notif_add_parent": "Add parent",
"panel.notif_custom_empty": "No custom notifications yet.",
diff --git a/custom_components/taskmate/www/locales/en.json b/custom_components/taskmate/www/locales/en.json
index 93b9e314..dda6fda4 100644
--- a/custom_components/taskmate/www/locales/en.json
+++ b/custom_components/taskmate/www/locales/en.json
@@ -1560,7 +1560,7 @@
"panel.tab_templates": "Templates",
"panel.tab_today": "Today",
"panel.tab_unknown": "Unknown tab",
- "panel.wiki_tooltip": "Open the TaskMate wiki",
+ "panel.wiki_tooltip": "Open the TaskMate documentation",
"panel.notif_add_custom": "Add custom notification",
"panel.notif_add_parent": "Add parent",
"panel.notif_custom_empty": "No custom notifications yet.",
diff --git a/custom_components/taskmate/www/locales/fr.json b/custom_components/taskmate/www/locales/fr.json
index c1ca54d4..815f8c81 100644
--- a/custom_components/taskmate/www/locales/fr.json
+++ b/custom_components/taskmate/www/locales/fr.json
@@ -1496,7 +1496,7 @@
"panel.tab_templates": "Modèles",
"panel.tab_today": "Aujourd'hui",
"panel.tab_unknown": "Onglet inconnu",
- "panel.wiki_tooltip": "Ouvrir le wiki TaskMate",
+ "panel.wiki_tooltip": "Ouvrir la documentation TaskMate",
"panel.notif_add_custom": "Ajouter une notification personnalisée",
"panel.notif_add_parent": "Ajouter un parent",
"panel.notif_custom_empty": "Aucune notification personnalisée pour l'instant.",
diff --git a/custom_components/taskmate/www/locales/nb.json b/custom_components/taskmate/www/locales/nb.json
index 86008448..099d08ea 100644
--- a/custom_components/taskmate/www/locales/nb.json
+++ b/custom_components/taskmate/www/locales/nb.json
@@ -1496,7 +1496,7 @@
"panel.tab_templates": "Maler",
"panel.tab_today": "I dag",
"panel.tab_unknown": "Ukjent fane",
- "panel.wiki_tooltip": "Åpne TaskMate-wikien",
+ "panel.wiki_tooltip": "Åpne TaskMate-dokumentasjonen",
"panel.notif_add_custom": "Legg til egendefinert varsel",
"panel.notif_add_parent": "Legg til foresatt",
"panel.notif_custom_empty": "Ingen egendefinerte varsler ennå.",
diff --git a/custom_components/taskmate/www/locales/nn.json b/custom_components/taskmate/www/locales/nn.json
index 57118c01..b07271e1 100644
--- a/custom_components/taskmate/www/locales/nn.json
+++ b/custom_components/taskmate/www/locales/nn.json
@@ -1496,7 +1496,7 @@
"panel.tab_templates": "Malar",
"panel.tab_today": "I dag",
"panel.tab_unknown": "Ukjend fane",
- "panel.wiki_tooltip": "Opne TaskMate-wikien",
+ "panel.wiki_tooltip": "Opne TaskMate-dokumentasjonen",
"panel.notif_add_custom": "Legg til eigendefinert varsel",
"panel.notif_add_parent": "Legg til føresett",
"panel.notif_custom_empty": "Ingen eigendefinerte varsel enno.",
diff --git a/custom_components/taskmate/www/locales/pl.json b/custom_components/taskmate/www/locales/pl.json
index 5d97d109..335a01ac 100644
--- a/custom_components/taskmate/www/locales/pl.json
+++ b/custom_components/taskmate/www/locales/pl.json
@@ -1560,7 +1560,7 @@
"panel.tab_templates": "Szablony",
"panel.tab_today": "Dziś",
"panel.tab_unknown": "Nieznana zakładka",
- "panel.wiki_tooltip": "Otwórz wiki TaskMate",
+ "panel.wiki_tooltip": "Otwórz dokumentację TaskMate",
"panel.notif_add_custom": "Dodaj własne powiadomienie",
"panel.notif_add_parent": "Dodaj rodzica",
"panel.notif_custom_empty": "Brak własnych powiadomień.",
diff --git a/custom_components/taskmate/www/locales/pt-BR.json b/custom_components/taskmate/www/locales/pt-BR.json
index 97ffbaaf..65860b46 100644
--- a/custom_components/taskmate/www/locales/pt-BR.json
+++ b/custom_components/taskmate/www/locales/pt-BR.json
@@ -1496,7 +1496,7 @@
"panel.tab_templates": "Modelos",
"panel.tab_today": "Hoje",
"panel.tab_unknown": "Aba desconhecida",
- "panel.wiki_tooltip": "Abrir a wiki do TaskMate",
+ "panel.wiki_tooltip": "Abrir a documentação do TaskMate",
"panel.notif_add_custom": "Adicionar notificação personalizada",
"panel.notif_add_parent": "Adicionar responsável",
"panel.notif_custom_empty": "Nenhuma notificação personalizada ainda.",
diff --git a/custom_components/taskmate/www/locales/pt.json b/custom_components/taskmate/www/locales/pt.json
index b454452d..ad955157 100644
--- a/custom_components/taskmate/www/locales/pt.json
+++ b/custom_components/taskmate/www/locales/pt.json
@@ -1501,7 +1501,7 @@
"panel.tab_templates": "Modelos",
"panel.tab_today": "Hoje",
"panel.tab_unknown": "Separador desconhecido",
- "panel.wiki_tooltip": "Abrir a wiki do TaskMate",
+ "panel.wiki_tooltip": "Abrir a documentação do TaskMate",
"panel.notif_add_custom": "Adicionar notificação personalizada",
"panel.notif_add_parent": "Adicionar encarregado",
"panel.notif_custom_empty": "Ainda não há notificações personalizadas.",
diff --git a/custom_components/taskmate/www/taskmate-panel.js b/custom_components/taskmate/www/taskmate-panel.js
index db03c790..25668057 100644
--- a/custom_components/taskmate/www/taskmate-panel.js
+++ b/custom_components/taskmate/www/taskmate-panel.js
@@ -3828,7 +3828,7 @@ class TaskMatePanel extends HTMLElement {
TaskMate
v${PANEL_VERSION}
-
+
diff --git a/mkdocs.yml b/mkdocs.yml
new file mode 100644
index 00000000..73dc39aa
--- /dev/null
+++ b/mkdocs.yml
@@ -0,0 +1,163 @@
+site_name: TaskMate
+site_url: https://tempus2016.github.io/taskmate/
+docs_dir: wiki
+edit_uri: edit/main/wiki/
+validation:
+ anchors: warn
+site_description: Chores, points and rewards for Home Assistant
+repo_url: https://github.com/tempus2016/taskmate
+repo_name: tempus2016/taskmate
+theme:
+ name: material
+ palette:
+ - media: "(prefers-color-scheme: light)"
+ scheme: default
+ primary: light blue
+ accent: amber
+ toggle: {icon: material/weather-night, name: Dark mode}
+ - media: "(prefers-color-scheme: dark)"
+ scheme: slate
+ primary: light blue
+ accent: amber
+ toggle: {icon: material/weather-sunny, name: Light mode}
+ icon:
+ logo: material/broom
+ features:
+ - navigation.tabs
+ - navigation.sections
+ - navigation.top
+ - navigation.instant
+ - search.suggest
+ - search.highlight
+ - content.code.copy
+ - content.action.edit
+ - toc.follow
+markdown_extensions:
+ - admonition
+ - attr_list
+ - tables
+ - toc:
+ permalink: true
+ slugify: !!python/object/apply:pymdownx.slugs.slugify {kwds: {case: lower}}
+ - pymdownx.superfences
+ - pymdownx.highlight
+ - pymdownx.details
+plugins:
+ - search
+nav:
+ - Home: index.md
+ - "Getting Started":
+ - "Installation": "Installation.md"
+ - "Getting Started": "Getting-Started.md"
+ - "Setup Wizard": "Setup-Wizard.md"
+ - "Ready-Made Dashboards": "Ready-Made-Dashboards.md"
+ - "Admin Panel": "Admin-Panel.md"
+ - "Children": "Children.md"
+ - "Adult Profiles": "Adult-Profiles.md"
+ - "Settings": "Settings.md"
+ - "Chores":
+ - "Chores": "Chores.md"
+ - "Chore Scheduling": "Chore-Scheduling.md"
+ - "Mandatory Chores": "Mandatory-Chores.md"
+ - "Difficulty Tiers": "Difficulty-Tiers.md"
+ - "Timed Tasks": "Timed-Tasks.md"
+ - "Weekly Targets": "Weekly-Targets.md"
+ - "Task Groups": "Task-Groups.md"
+ - "Bonus Subtasks": "Bonus-Subtasks.md"
+ - "Photo Proof": "Photo-Proof.md"
+ - "Open-Ended Chores": "Open-Ended-Chores.md"
+ - "Chore Swaps": "Chore-Swaps.md"
+ - "Chore Dependencies": "Chore-Dependencies.md"
+ - "To-Do Lists": "To-Do-Lists.md"
+ - "Vacation Mode": "Vacation-Mode.md"
+ - "Calendar": "Calendar.md"
+ - "Dynamic Chore Visibility": "Dynamic-Chore-Visibility.md"
+ - "Weather-Aware Chores": "Weather-Aware-Chores.md"
+ - "Reactive Chores": "Reactive-Chores.md"
+ - "Scheduled Config Changes": "Scheduled-Config-Changes.md"
+ - "Chore Roulette": "Chore-Roulette.md"
+ - "Teamwork Chores": "Teamwork-Chores.md"
+ - "NFC Tag Completion": "NFC-Tag-Completion.md"
+ - "Two-Way Calendar": "Two-Way-Calendar.md"
+ - "Chore Auctions": "Chore-Auctions.md"
+ - "Quality Ratings": "Quality-Ratings.md"
+ - "Reject Reasons": "Reject-Reasons.md"
+ - "Surprise Inspections": "Surprise-Inspections.md"
+ - "Child Undo Window": "Child-Undo-Window.md"
+ - "Logging Past Jobs": "Logging-Past-Jobs.md"
+ - "Estimated Minutes": "Estimated-Minutes.md"
+ - "Reference Photos": "Reference-Photos.md"
+ - "Quantity Chores": "Quantity-Chores.md"
+ - "Auto-Approve": "Auto-Approve.md"
+ - "Help Requests": "Help-Requests.md"
+ - "Sick Days": "Sick-Days.md"
+ - "Points, Rewards & Economy":
+ - "Rewards": "Rewards.md"
+ - "Managing Rewards": "Managing-Rewards.md"
+ - "Pool Mode (Savings Jars)": "Pool-Mode-(Savings-Jars).md"
+ - "Bonus Points": "Bonus-Points.md"
+ - "Bonuses": "Bonuses.md"
+ - "Penalties": "Penalties.md"
+ - "Make-It-Right Penalties": "Make-It-Right-Penalties.md"
+ - "Points Economy": "Points-Economy.md"
+ - "Gifting Points": "Gifting-Points.md"
+ - "Allowance": "Allowance.md"
+ - "Family Goals": "Family-Goals.md"
+ - "Timed Unlock Rewards": "Timed-Unlock-Rewards.md"
+ - "Time-Locked Rewards": "Time-Locked-Rewards.md"
+ - "External Lock-Screen Shops": "External-Lock-Screen-Shops.md"
+ - "Bounty Board": "Bounty-Board.md"
+ - "Wishlist": "Wishlist.md"
+ - "Raffles": "Raffles.md"
+ - "Gamification":
+ - "Levels & XP": "Levels-and-XP.md"
+ - "Achievement Badges": "Achievement-Badges.md"
+ - "Quests": "Quests.md"
+ - "Challenges": "Challenges.md"
+ - "Avatars": "Avatars.md"
+ - "Celebrations": "Celebrations.md"
+ - "Leaderboard Seasons": "Leaderboard-Seasons.md"
+ - "Streak Freezes": "Streak-Freezes.md"
+ - "Birthday Mode": "Birthday-Mode.md"
+ - "Recaps": "Recaps.md"
+ - "Virtual Pets": "Virtual-Pets.md"
+ - "Weekly Goals": "Weekly-Goals.md"
+ - "Notifications & Admin":
+ - "Notifications": "Notifications.md"
+ - "Quiet Hours": "Quiet-Hours.md"
+ - "Presence-Aware Reminders": "Presence-Aware-Reminders.md"
+ - "Reminder Escalation": "Reminder-Escalation.md"
+ - "Weekly Digest": "Weekly-Digest.md"
+ - "Admin Audit Log": "Admin-Audit-Log.md"
+ - "Multi-Parent Approval Routing": "Multi-Parent-Approval-Routing.md"
+ - "Insights": "Insights.md"
+ - "Mood Check-In": "Mood-Check-In.md"
+ - "Parent Access": "Parent-Access.md"
+ - "Backup & Restore": "Backup-and-Restore.md"
+ - "Repairs & Diagnostics": "Repairs-and-Diagnostics.md"
+ - "Reference":
+ - "Dashboard Cards": "Dashboard-Cards.md"
+ - "Routine Mode": "Routine-Mode.md"
+ - "Kiosk Mode": "Kiosk-Mode.md"
+ - "Sticker Chart Card": "Sticker-Chart-Card.md"
+ - "Watch Complications": "Watch-Complications.md"
+ - "Pre-Reader Mode": "Pre-Reader-Mode.md"
+ - "Card Design Styles": "Card-Design-Styles.md"
+ - "Read Aloud": "Read-Aloud.md"
+ - "Template Packs": "Template-Packs.md"
+ - "Printable Weekly Chart": "Printable-Weekly-Chart.md"
+ - "Completion Sounds": "Completion-Sounds.md"
+ - "Guest Child Profiles": "Guest-Child-Profiles.md"
+ - "Configuration Entities": "Configuration-Entities.md"
+ - "Voice Assistants": "Voice-Assistants.md"
+ - "Services": "Services.md"
+ - "Sensor Reference": "Sensor-Reference.md"
+ - "Sensor Attributes": "Sensor-Attributes.md"
+ - "Event Entities": "Event-Entities.md"
+ - "Approvals Card": "Approvals-Card.md"
+ - "Visibility Configuration Guide": "Visibility-Configuration-Guide.md"
+ - "Visibility Operators Reference": "Visibility-Operators-Reference.md"
+ - "Automations": "Automations.md"
+ - "Localization": "Localization.md"
+ - "Troubleshooting": "Troubleshooting.md"
+ - "FAQ": "FAQ.md"
diff --git a/requirements-docs.txt b/requirements-docs.txt
new file mode 100644
index 00000000..3ce3a829
--- /dev/null
+++ b/requirements-docs.txt
@@ -0,0 +1,4 @@
+# Builds the documentation site (wiki/ -> GitHub Pages). See .github/workflows/docs.yml.
+# MkDocs 2.0 drops the plugin and theme system Material depends on, so stay on 1.x.
+mkdocs>=1.6,<2
+mkdocs-material>=9.6,<10
diff --git a/wiki/Achievement-Badges.md b/wiki/Achievement-Badges.md
new file mode 100644
index 00000000..c598237b
--- /dev/null
+++ b/wiki/Achievement-Badges.md
@@ -0,0 +1,391 @@
+# Achievement Badges
+
+Milestone-based recognition layered on top of the existing chores, streaks, and rewards systems. 15 built-in badges across four tiers (Bronze, Silver, Gold, Platinum), plus full support for parent-created custom badges with multi-criterion rules combined with AND or OR logic.
+
+
+
+
+---
+
+## How It Works
+
+```
+Child reaches milestone → Badge auto-awarded → Optional point bonus + notification
+```
+
+Badges are evaluated automatically whenever a child's stats change (chore completion, streak update, perfect week, etc.). When all criteria for a badge are met, it is awarded instantly. Parents can also award badges manually for anything that doesn't fit a metric.
+
+---
+
+## Tiers
+
+Each badge belongs to a tier that determines its visual styling and prestige:
+
+| Tier | Colour | Description |
+|------|--------|-------------|
+| **Bronze** | `#e08a3c` | Entry-level achievements |
+| **Silver** | `#a8b8c8` | Intermediate milestones |
+| **Gold** | `#ffc107` | Significant accomplishments |
+| **Platinum** | `#4dd9e8` | Elite achievements |
+
+---
+
+## Built-in Catalogue
+
+15 built-in badges ship with TaskMate. Their criteria, name, description, and icon are frozen so installs stay consistent — but you can toggle them on/off and edit their `point_bonus`, tier, assignment, and notify-on-earn settings.
+
+| Tier | Badge | Criteria |
+|------|-------|----------|
+| Bronze | First Chore | Complete 1 chore |
+| Bronze | First Reward | Claim 1 reward |
+| Bronze | 100 Points | Earn 100 total points |
+| Bronze | 10 Chores Completed | Complete 10 chores |
+| Silver | 500 Points | Earn 500 total points |
+| Silver | 50 Chores | Complete 50 chores |
+| Silver | 3-Day Streak | Reach a 3-day streak |
+| Silver | First Perfect Week | Earn 1 perfect week |
+| Gold | 1000 Points | Earn 1000 total points |
+| Gold | 100 Chores | Complete 100 chores |
+| Gold | 7-Day Streak | Reach a 7-day streak |
+| Gold | 5 Perfect Weeks | Earn 5 perfect weeks |
+| Platinum | 5000 Points | Earn 5000 total points |
+| Platinum | 30-Day Streak | Reach a 30-day streak |
+| Platinum | 10 Perfect Weeks | Earn 10 perfect weeks |
+
+---
+
+## Custom Badges
+
+Create your own badges via the Admin Panel or services. Custom badges support any combination of metric criteria, each with its own comparison operator, combined with either **AND** or **OR** logic.
+
+- **AND** (default) — every criterion must pass for the badge to auto-award.
+- **OR** — the badge auto-awards as soon as *any one* criterion passes.
+
+The combinator is set per badge with the `combinator` field (`AND` or `OR`).
+
+### Operators
+
+Each criterion is a `{ metric, operator, value }` object. The `operator` controls how the child's current metric value is compared against `value`:
+
+| Operator | Meaning |
+|----------|---------|
+| `>=` | Greater than or equal (default) |
+| `>` | Strictly greater than |
+| `<=` | Less than or equal |
+| `<` | Strictly less than |
+| `==` | Exactly equal |
+| `!=` | Not equal |
+
+If `operator` is omitted or unrecognised, TaskMate falls back to `>=`.
+
+### Available Metrics
+
+| Metric | Description | Example |
+|--------|-------------|---------|
+| `total_points` | Lifetime points earned | `total_points >= 2000` |
+| `total_chores` | Lifetime chores completed | `total_chores >= 50` |
+| `total_rewards` | Lifetime rewards claimed | `total_rewards >= 5` |
+| `current_streak` | Current consecutive-day streak | `current_streak >= 14` |
+| `best_streak` | Best streak ever achieved | `best_streak >= 30` |
+| `perfect_weeks` | Total perfect weeks earned | `perfect_weeks >= 3` |
+| `first_chore` | First chore completed (use value `1`) | `first_chore >= 1` |
+| `first_reward` | First reward claimed (use value `1`) | `first_reward >= 1` |
+
+### Empty Criteria = Manual Award Only
+
+A badge with no criteria can only be awarded by a parent pressing "Award to…" in the admin panel or calling `taskmate.award_badge_manually`. Use this for subjective achievements like "Best Helper This Week" or "Great Attitude".
+
+### Multi-Criterion Example (AND)
+
+```yaml
+service: taskmate.add_badge
+data:
+ name: "Holiday Helper"
+ description: "Earned for big effort during school holidays"
+ icon: mdi:beach
+ tier: silver
+ point_bonus: 30
+ criteria:
+ - { metric: total_chores, operator: ">=", value: 20 }
+ - { metric: current_streak, operator: ">=", value: 3 }
+ combinator: AND
+ assigned_to: [child_id_1, child_id_2]
+ notify_on_earn: true
+```
+
+With `combinator: AND` (the default), both criteria must be true at the same time for the badge to auto-award.
+
+### Multi-Criterion Example (OR)
+
+```yaml
+service: taskmate.add_badge
+data:
+ name: "All-Rounder"
+ description: "Hit any one of these big targets"
+ icon: mdi:star-shooting
+ tier: gold
+ point_bonus: 50
+ criteria:
+ - { metric: total_points, operator: ">=", value: 1000 }
+ - { metric: best_streak, operator: ">=", value: 14 }
+ - { metric: perfect_weeks, operator: ">=", value: 5 }
+ combinator: OR
+ notify_on_earn: true
+```
+
+With `combinator: OR`, the badge auto-awards as soon as the child meets *any one* of the three targets.
+
+### Using Other Operators
+
+Operators other than `>=` let you target exact or upper-bound values:
+
+```yaml
+service: taskmate.add_badge
+data:
+ name: "Comeback Kid"
+ description: "Back on track after a slip"
+ icon: mdi:restart
+ tier: bronze
+ point_bonus: 10
+ criteria:
+ - { metric: current_streak, operator: "==", value: 1 }
+ - { metric: total_chores, operator: ">", value: 50 }
+ combinator: AND
+```
+
+---
+
+## Point Bonuses
+
+Each badge can award optional bonus points when earned. The bonus is a one-time credit applied at the moment the badge is awarded.
+
+- Set `point_bonus` when creating or editing a badge (default: 0)
+- The bonus is credited to the child's balance and logged as a transaction
+- If a badge is **revoked**, the bonus is automatically reversed (deducted from the child's balance)
+- Silent backfill (see below) never credits point bonuses — only live awards do
+
+---
+
+## Retroactive Backfill
+
+When TaskMate is first updated to a version with badges (v3.8.0+), or when a previously-disabled built-in badge is re-enabled, badges are silently awarded for milestones children have already passed.
+
+- A child with 200 lifetime points instantly receives the "100 Points" badge
+- Silent backfill **never fires notifications** and **never credits point bonuses**
+- The feature works on day one without causing point inflation
+
+Use `taskmate.rebuild_badges` to manually re-run the backfill sweep (e.g. after enabling a previously-disabled built-in or tweaking custom badge criteria).
+
+---
+
+## Display
+
+### Badges Card
+
+The dedicated `taskmate-badges-card` shows a full grid view of all badges for one or all children.
+
+```yaml
+type: custom:taskmate-badges-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+header_color: "#764ba2"
+```
+
+**Features:**
+- Earned badges show in full tier colour with icon, name, earned date, and point bonus badge
+- Locked badges show greyed out with a progress bar and the closest-criterion completion percentage. *(Those bars only started drawing in v5.1.1 — they read a `closest_criterion` field that nothing had ever published.)*
+- Tier filter dropdown (All / Bronze / Silver / Gold / Platinum)
+- Newly-earned badges animate with a pop + shimmer effect
+- Detects a new badge from the badges sensor, so the highlight works for every user. Before v5.0.4 the card subscribed to the `taskmate_badge_earned` bus event, which Home Assistant refuses for non-admin users — that logged an error on every dashboard load and the highlight never fired
+
+### Child Card Badge Strip
+
+The child card shows an inline strip of up to 5 most-recently-earned badges below the points readout. Auto-hidden when the child has zero earned badges.
+
+- Tap the strip to open the admin panel's badges section
+- Disable with `show_badges: false` on the child card
+
+### Child Card — Next Badge Progress (v5.1.1+)
+
+Under the earned strip, the child card shows a compact **Next up** line for the closest unearned badge: tier-coloured icon, badge name, a thin progress bar and a `845 / 1000` count taken from the badge's closest criterion.
+
+Before v5.1.1 the child card only ever showed badges already won, so a child working toward a long badge got no feedback until it popped — that progress lived only in the Badges card.
+
+- Auto-hidden when there is nothing left to earn, or when every remaining badge is still at 0%
+- Tap it to open the admin panel's badges section, same as the earned strip
+- Rendered on all six [design styles](Card-Design-Styles.md)
+- Disable with `show_next_badge: false` on the child card
+
+#### "One more and it's yours!" (v5.8.0+)
+
+When that badge is **one unit short** of its target, a short line of encouragement appears under the bar (#893).
+
+Distance is measured in the criterion's own units rather than a percentage, because 90% of a ten-week badge is a week away while 90% of a hundred-point badge is ten points away. It is deliberately rare — a line that shows for half the climb has stopped meaning anything by the time it matters.
+
+- Badges you award by hand carry no criterion, so they never nudge
+- Disable with `show_badge_nudge: false` on the child card
+
+### Admin Panel — Badges Section
+
+Three tabs in the admin panel's Badges area:
+
+| Tab | Content |
+|-----|---------|
+| **Catalogue** | Built-in badges with enable/disable toggles and editable settings |
+| **Custom** | Create, edit, and delete custom badges |
+| **Award History** | All awarded badges with AUTO / MANUAL / SILENT source pills and one-click revoke |
+
+Revoking a badge from the Award History tab automatically reverses any point bonus that was credited.
+
+---
+
+## Sensor
+
+Each child gets a dedicated badge sensor:
+
+**Entity:** `sensor.taskmate__badges`
+
+| Field | Description |
+|-------|-------------|
+| **State** | Count of earned badges |
+| **`earned`** | Array of earned badge objects with `badge_id`, `name`, `tier`, `icon`, `earned_at`, `source` (auto/manual/silent), `point_bonus` |
+| **`available`** | Array of all available badges with `badge_id`, `name`, `tier`, `progress_pct`, `criteria`, and (v5.1.1+) `closest_criterion` — `{metric, current, target}` for the criterion nearest completion |
+| **`total_badges`** | Total number of badges in the system |
+
+---
+
+## Notifications
+
+When a badge auto-earns, TaskMate sends:
+
+1. A **persistent HA notification** (in the notification bell)
+2. An optional **mobile push notification** (if notification routing is configured for badge_earned — see [Notifications](Notifications.md))
+3. A **`taskmate_badge_earned`** bus event for power users
+
+Per-badge `notify_on_earn` toggle controls whether notifications fire (default: `true`).
+
+When 3 or more badges earn in a single evaluation cycle, notifications are batched into a single combined message instead of firing separately.
+
+Streaks themselves can also fire a separate **streak milestone** notification when a child reaches a streak milestone. It is off by default — opt in on the Notifications tab. See [Notifications](Notifications.md).
+
+---
+
+## Services
+
+### `taskmate.add_badge`
+
+Create a custom badge.
+
+| Field | Required | Default | Description |
+|-------|----------|---------|-------------|
+| `name` | Yes | — | Badge display name |
+| `description` | No | `""` | Description text |
+| `icon` | No | `mdi:medal` | MDI icon |
+| `tier` | No | `bronze` | `bronze`, `silver`, `gold`, or `platinum` |
+| `point_bonus` | No | `0` | Bonus points awarded on earn |
+| `criteria` | No | `[]` | List of `{metric, operator, value}` objects. `operator` is one of `>=`, `>`, `<=`, `<`, `==`, `!=` (defaults to `>=`). Empty = manual-award only |
+| `combinator` | No | `AND` | How criteria combine: `AND` (all must pass) or `OR` (any) |
+| `assigned_to` | No | all children | List of child IDs — empty = all children |
+| `notify_on_earn` | No | `true` | Fire notifications when earned |
+
+### `taskmate.update_badge`
+
+Update an existing badge. Only supplied fields are changed. Built-in badges allow editing `point_bonus`, `tier`, `assigned_to`, `notify_on_earn`, and `enabled` only — criteria, name, description, and icon are frozen.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `badge_id` | Yes | ID of the badge to update |
+| `name` | No | New name (custom only) |
+| `description` | No | New description (custom only) |
+| `icon` | No | New icon (custom only) |
+| `tier` | No | New tier |
+| `point_bonus` | No | New point bonus |
+| `criteria` | No | New criteria list (custom only) — same `{metric, operator, value}` shape as `add_badge` |
+| `combinator` | No | New combinator (custom only) — `AND` or `OR` |
+| `assigned_to` | No | New child ID list |
+| `notify_on_earn` | No | New notification setting |
+
+### `taskmate.remove_badge`
+
+Delete a custom badge. Built-in badges cannot be removed — disable them instead via `update_badge`.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `badge_id` | Yes | ID of the badge to remove |
+
+### `taskmate.award_badge_manually`
+
+Manually award a badge to a child, bypassing criteria evaluation.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `badge_id` | Yes | ID of the badge to award |
+| `child_id` | Yes | ID of the child |
+
+Point bonus is credited. Notification fires if `notify_on_earn` is true. The award is recorded with source `MANUAL`.
+
+### `taskmate.revoke_badge`
+
+Revoke a previously awarded badge. Automatically reverses any point bonus that was credited.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `awarded_badge_id` | Yes | ID of the awarded badge record (from the Award History in the admin panel or the sensor's `earned` array) |
+
+### `taskmate.rebuild_badges`
+
+Re-evaluate all badges across all children silently. Awards any newly-qualifying badges without firing notifications or crediting point bonuses. Useful after:
+
+- Enabling a previously-disabled built-in badge
+- Changing custom badge criteria
+- Fixing data inconsistencies
+
+No parameters required.
+
+---
+
+## Automation Examples
+
+### Announce badge on a smart speaker
+
+```yaml
+alias: Announce badge earned
+triggers:
+ - trigger: event
+ event_type: taskmate_badge_earned
+actions:
+ - action: tts.google_translate_say
+ data:
+ entity_id: media_player.kitchen_speaker
+ message: >
+ Congratulations {{ trigger.event.data.child_name }}!
+ You earned the {{ trigger.event.data.badge_name }} badge!
+```
+
+### Flash lights on platinum badge
+
+```yaml
+alias: Platinum badge celebration
+triggers:
+ - trigger: event
+ event_type: taskmate_badge_earned
+conditions:
+ - condition: template
+ value_template: "{{ trigger.event.data.tier == 'platinum' }}"
+actions:
+ - action: light.turn_on
+ target:
+ entity_id: light.living_room
+ data:
+ flash: long
+ color_name: cyan
+```
+
+---
+
+## Related
+
+- [Bonus Points](Bonus-Points.md) — streak milestones and perfect weeks (badge criteria sources)
+- [Dashboard Cards](Dashboard-Cards.md) — badges card and child card badge strip
+- [Notifications](Notifications.md) — notification routing for badge_earned events
+- [Services](Services.md) — full service reference
diff --git a/wiki/Admin-Audit-Log.md b/wiki/Admin-Audit-Log.md
new file mode 100644
index 00000000..fb06ab8c
--- /dev/null
+++ b/wiki/Admin-Audit-Log.md
@@ -0,0 +1,66 @@
+# Admin Audit Log
+
+The admin audit log records every change made through the TaskMate admin panel — who made it, what it was, and when. It gives parents a simple history of administrative actions on the family's TaskMate setup.
+
+
+
+Added in v4.0.0.
+
+---
+
+## What Is Logged
+
+Every **successful, state-changing** admin command issued through the panel is recorded. Each entry captures:
+
+| Field | Description |
+|-------|-------------|
+| **When** | Timestamp of the action (ISO 8601, shown in your local format) |
+| **User** | The Home Assistant user who made the change — display name, falling back to user id |
+| **Action** | The command name, e.g. `add_chore`, `update_reward`, `remove_child`, `apply_penalty` |
+| **Target** | A best-effort, human-readable subject of the action |
+
+### How the target is resolved
+
+TaskMate fills the **Target** field on a best-effort basis, in this order:
+
+1. The `name` in the request payload, if present (e.g. the name of a chore being created).
+2. The resolved name of the referenced chore, child, or reward (`chore_id` / `child_id` / `reward_id`).
+3. The raw id of another referenced object (`penalty_id`, `bonus_id`, `badge_id`, `group_id`, `template_id`, `completion_id`, `claim_id`, `parent_id`, `custom_id`, `awarded_badge_id`, `type_id`).
+
+If none of these apply, the target is left blank.
+
+### What is NOT logged
+
+Read-only and audit-management commands do not create entries — fetching panel state, listing notify services, listing/getting templates, reading the notification config, and listing or clearing the audit log itself. Only commands that mutate data are recorded.
+
+> Actions taken outside the panel (TaskMate **services** called from automations or scripts) are not captured by the panel audit log. Use the relevant [bus events](Automations.md#bus-events-reference) to track those.
+
+---
+
+## Where to View It
+
+Open the **Admin Panel** and select the **Audit** tab. It shows a table of recent admin changes (When · User · Action · Target), newest first. The panel loads the newest 100 entries with the rest of its state.
+
+See [Admin Panel](Admin-Panel.md) for how to open the panel.
+
+---
+
+## Retention & Limits
+
+- The log is capped at **500 entries**. When full, the oldest entry is dropped as new ones are added.
+- Entries are stored in TaskMate's own Store and persist across restarts.
+- Entries are included in a [backup export](Backup-and-Restore.md).
+
+---
+
+## Clearing the Log
+
+A **Clear log** button on the Audit tab removes all entries after a confirmation prompt. This cannot be undone. Clearing the log is itself not recorded as an entry.
+
+---
+
+## Related
+
+- [Admin Panel](Admin-Panel.md) — where the Audit tab lives
+- [Backup and Restore](Backup-and-Restore.md) — the log is included in exports
+- [Automations](Automations.md) — bus events for tracking actions taken outside the panel
diff --git a/wiki/Admin-Panel.md b/wiki/Admin-Panel.md
new file mode 100644
index 00000000..e8e81f6f
--- /dev/null
+++ b/wiki/Admin-Panel.md
@@ -0,0 +1,314 @@
+# Admin Panel
+
+The Admin Panel is a web-based management dashboard accessible from the Home Assistant sidebar. It provides a single interface for managing all TaskMate configuration without navigating through the standard HA integration settings.
+
+
+
+---
+
+## Accessing the Panel
+
+After installing TaskMate, a **TaskMate** entry appears in the HA sidebar with the icon `mdi:checkbox-marked-circle-plus-outline`.
+
+Click it to open the panel at `/taskmate-admin`.
+
+> **Note:** The panel requires an **admin** HA user. Non-admin users will not see the sidebar entry.
+
+---
+
+## Today (v6.0.0+)
+
+The panel opens on **Today**, a single page that shows how the day is going and everything that needs you.
+
+- **A card per child** with today's done/total ring, their points and streak, and a **±** button to give or take points. Click a child's card to filter the whole panel to them.
+- **Needs you** gathers everything waiting on a parent in one list: chore and bounty approvals, reward claims, swap requests, new wishes and open [surprise inspections](Surprise-Inspections.md). **Approve all** clears the chore approvals in one go.
+- **Chore board** shows each child's chores for today, grouped by time of day and marked done, awaiting approval, to do or missed. Click a chore to open its editor. The **This week** tab shows each day's done/total.
+- **Quick actions** (new chore, new bounty, give a bonus, apply a penalty) and **Recent activity**.
+- **Asked for help** *(v7.0.0)* lists each open "I'm stuck" request: who, which chore, their message and when. **On my way** marks it answered, so the child's card stops saying help is on its way. See [Help Requests](Help-Requests.md).
+- **Sick day** *(v7.0.0)* — the 🤒 button on each child's card gives them a sick day today (chores hidden, streak safe, no mandatory chore missed); tap it again to take it back. The card shows a **Sick day** pill, and a **Mood** pill with today's face once the child has done the [mood check-in](Mood-Check-In.md). See [Sick Days](Sick-Days.md).
+
+When there are no children yet, Today offers **Start setup** (the [Setup Wizard](Setup-Wizard.md)) or **Add a child myself** instead.
+
+---
+
+## Navigation
+
+On the **desktop**, the sidebar groups sections by what you're doing, each with a live count badge:
+
+| Group | Sections |
+|-------|----------|
+| **Family** | Children, Groups |
+| **Earn** | Chores, Bounties, Auctions, Quests, Challenges, Templates |
+| **Spend** | Rewards, Wishlists, Raffles (v7.0.0) |
+| **Adjust** | Bonuses, Penalties, Badges |
+| **Review** | Activity, Insights, Audit |
+| **System** | Notifications, Settings |
+
+Click a group heading to collapse it, and use **«** at the top to shrink the sidebar to icons. Both are remembered in your browser.
+
+On a **phone**, a bottom bar gives one-tap access to **Today**, **Chores**, **Rewards** and **Children**, with **More** for everything else. The section picker at the top (added in v4.5.1) still lists every section, grouped the same way.
+
+### Command search (Ctrl K)
+
+Press **Ctrl K** (**⌘ K** on a Mac), or **/**, or click **Search or jump to…** in the top bar. Start typing to jump straight to any section, chore, reward, quest, challenge or child, or to run an action such as *Approve all*, *Give points*, *New chore* or *Run setup wizard*. Use the arrow keys and **Enter** to pick, **Esc** to close.
+
+
+
+### Child filter
+
+The row of faces in the top bar filters the panel to one child. With a child picked, Today, Children, Chores, Rewards, Quests, Challenges, Bonuses, Penalties, Activity and Wishlists show only what concerns them. A banner reminds you the filter is on; **Show everyone** (or **All**) clears it.
+
+
+
+### New menu
+
+The **+ New** button in the top bar creates a chore, bounty, reward, quest, challenge, child or auction from anywhere in the panel.
+
+---
+
+## What You Can Do
+
+The admin panel provides full management for every aspect of TaskMate:
+
+### Child Management
+- Add new children with name and avatar
+- Edit existing children (name, avatar, availability entities)
+- Show a child's **photo** from their person entity instead of an icon (v6.4.0+, see [Children](Children.md#child-photos))
+- Mark a profile as an **adult** with the **Adult profile** switch (v6.4.0+, see [Adult Profiles](Adult-Profiles.md))
+- **Log a past job** for a job done on an earlier day that nobody ticked (v6.4.0+, see [Logging Past Jobs](Logging-Past-Jobs.md))
+- Pick each child's **Colour** (v7.0.0+), which marks their avatar and name around the panel; *Automatic* picks one from their place in the list
+- Remove children
+- Set a **Kiosk PIN** for the shared wall tablet (v6.0.0+, see [Kiosk Mode](Kiosk-Mode.md))
+- View child stats (points, streaks, completions)
+- **Adjust points inline (v5.1.0+)** — each child card carries a row of quick buttons, **−20 −10 −5** and **+5 +10 +20** by default, plus **⋯** for a custom amount with an optional reason. Change the amounts in **Settings → Quick point amounts** (a comma-separated list, e.g. `5, 10, 20`). Every adjustment lands in the activity feed and can be undone from there.
+
+### Chore Management
+- Create chores with all configuration options
+- Edit any chore field including assignment mode, scheduling, visibility, and bonus subtasks
+- Configure timed task settings (rate, cap)
+- Delete chores
+- Reorder chores per child
+
+#### The chore editor (v6.0.0+)
+
+Adding or editing a chore opens the editor as a **side panel** on the right, so the list stays visible behind it. On a phone it fills the screen. The same editor opens from the Chores list, the Today chore board, command search and the **New** menu.
+
+Its fields are grouped under five headings: **Basics**, **Who does it**, **When**, **Checking** and **More options**. More options holds the less-used sections: teamwork, bonus sub-tasks, NFC / QR tags, visibility and calendar, scheduled changes and weather. **Delete** sits in the footer when you're editing an existing chore, and **Esc** closes the panel. Nothing was removed from the old dialog; the fields are just grouped differently.
+
+
+
+#### Chore row actions — kebab menu (v4.2.0+)
+
+The **Chores** table collapses each row's per-row actions into a **⋮ kebab menu**. **Edit** stays inline; everything else lives in the menu:
+
+- *Parent did it (no points)*
+- *Auction an occurrence* (v6.0.0+, see [Chore Auctions](Chore-Auctions.md))
+- *Deactivate / Activate chore*
+- *Skip* (rotation modes)
+- *Swap* (rotation / first-come)
+- *Duplicate*
+- *Delete*
+
+This also fixed the wide-screen horizontal scrolling the old inline button row caused.
+
+**v4.3.0:** the **Edit** and **⋮** controls now sit inside the pinned task-name column, so they stay reachable next to each chore's title even when a wide table scrolls horizontally — no more scrolling to the far right to reach a row's actions. In bulk-select mode the name column un-pins and the actions scroll with it.
+
+
+
+### Reward Management
+- Create rewards with cost, icon, and assignment
+- Toggle pool mode (savings jar) per reward
+- Configure jackpot rewards
+- Set quantity limits and expiration dates
+- Delete rewards
+
+### Bounties, Wishlists and Auctions (v6.0.0+)
+- **Bounties** — post one-off jobs any eligible child can claim, and follow them through Active, Waiting approval and History. See [Bounty Board](Bounty-Board.md)
+- **Wishlists** — approve or decline children's wishes, record family pledges and fulfil funded wishes. See [Wishlist](Wishlist.md)
+- **Auctions** — put one day of an unpopular chore up for sealed bids. See [Chore Auctions](Chore-Auctions.md)
+
+### Raffles (v7.0.0+)
+The **Raffles** tab, under **Spend**, lists every raffle with its ticket price, tickets bought per child and the result.
+- **New raffle** — name, prize, a fixed ticket price, the most tickets per child (0 = no limit), when it is drawn, and which children may take part (empty = everyone). Once anyone has bought a ticket the price can't change
+- **Draw now** picks the winner straight away instead of waiting for the draw time
+- **Call off** cancels an open raffle and refunds every ticket
+- Children buy tickets on the [Raffle card](Dashboard-Cards.md#raffle-card). See [Raffles](Raffles.md)
+
+### Penalty & Bonus Management
+- Create, edit, and delete penalty/bonus definitions
+- *(v7.0.0)* Give a penalty a **Make it right** chore, so the child can earn some or all of it back. See [Make-It-Right Penalties](Make-It-Right-Penalties.md)
+- Apply penalties and bonuses to children directly
+
+### Task Group Management
+- Create task groups with sticky or spread policy
+- Select which chores belong to each group
+- Edit and delete groups
+
+### Settings
+- Configure all global settings:
+ - Points currency name and icon
+ - Weekend multiplier
+ - Streak reset mode and milestones
+ - Perfect week bonus
+ - Notification service
+ - Calendar projection days
+ - History retention
+ - Time-of-day boundaries (morning/afternoon/evening/night windows)
+ - Default card design selector (see [Card Design Styles](Card-Design-Styles.md))
+ - Show IDs toggle (see below)
+ - **Setup wizard** (v6.0.0+) — run the guided setup again to add more. See [Setup Wizard](Setup-Wizard.md)
+ - **Ready-made dashboards** (v6.3.0+) — create a Kids, Parents or Wall tablet dashboard filled in with your family. See [Ready-Made Dashboards](Ready-Made-Dashboards.md)
+ - **Recaps** (v6.0.0+) — how often each child gets a Wrapped-style recap. See [Recaps](Recaps.md)
+ - **Surprise inspections** (v6.0.0+) — the bonus, window and random daily pick. See [Surprise Inspections](Surprise-Inspections.md)
+ - **Auto-approve after (hours)** (v7.0.0+) — approve chores nobody reviewed in time. See [Auto-Approve](Auto-Approve.md)
+ - **Virtual pets** (v7.0.0+) — switch pets on and tune how they grow. See [Virtual Pets](Virtual-Pets.md)
+ - **Personal weekly goals** (v7.0.0+) — let children set their own weekly target, and the bonus for reaching it. See [Weekly Goals](Weekly-Goals.md)
+
+### Badge Management
+- View built-in badge catalogue with enable/disable toggles
+- Edit built-in badge settings (tier, point bonus, assignment, notify-on-earn)
+- Create, edit, and delete custom badges with multi-criterion rules
+- View award history with AUTO / MANUAL / SILENT source indicators
+- Revoke awarded badges with automatic point bonus reversal
+
+### Insights (v5.0.0+)
+- **Fairness** — each child's share of the work over 7 / 14 / 30 days, flagged when someone is more than 15 percentage points off an even split
+- **Friction** — which chores actually get done versus how often they come up, with a suggested action per chore
+- **Week ahead** — chores and points projected across the next 7 / 14 / 28 days, including rotation
+- **Health** — configuration problems (broken dependencies, deleted children, missing entities) with a **Show me** jump to each
+- **Moods** (v7.0.0) — each child's end-of-day mood check-ins, with a count of tough days. The fairness view also shows [estimated minutes](Estimated-Minutes.md) when chores have them
+- See [Insights](Insights.md)
+
+### Templates (v4.0.0+)
+- Browse built-in chore template packs and create chores from them
+- Save your own chores as a custom template
+- Export custom templates as a shareable pack, and import one somebody else made
+- See [Template Packs](Template-Packs.md)
+
+### Notification Management (v3.9.0+)
+- Configure per-child notify services
+- Add, edit, and delete parent recipients
+- Configure the recipient routing matrix (which recipients get which notification types)
+- Set per-recipient bedtime times for bedtime reminders
+- Set global streak-at-risk cutoff time
+- Create, edit, and delete custom scheduled notifications with day masks and recipient selection
+- Send a test notification per type to verify routing (see [Notifications](Notifications.md#testing-a-notification))
+- Choose how parent approvals are routed — everyone, whoever is home, or round-robin (see [Multi-Parent Approval Routing](Multi-Parent-Approval-Routing.md))
+
+### Audit Log (v4.0.0+)
+- View a record of every admin change made through the panel (who, what, when)
+- See [Admin Audit Log](Admin-Audit-Log.md)
+
+### Approval Workflows
+- Approve or reject pending chore completions
+- Approve or reject pending reward claims
+
+---
+
+## Configuration Lives in the Panel (v4.0.0+)
+
+The deprecated **options / configure flow** (Settings → Devices & Services → TaskMate → Configure) was retired in v4.0.0. The admin panel at `/taskmate-admin` is now the sole configuration UI for day-to-day management — children, chores, rewards, task groups, settings, notifications, badges, and templates. Only the **initial setup** (points name and icon) still happens through a config flow when you first add the integration.
+
+No data migration is needed: all TaskMate data lives in the integration's own Store, not in the config entry's options.
+
+---
+
+## Backup & Restore (v4.0.0+)
+
+The **Settings** tab includes a **Backup & restore** section:
+
+- **Export backup** downloads a full JSON snapshot of your TaskMate setup (`taskmate-backup.json`).
+- **Restore backup** uploads a backup file and, after a confirmation prompt, **replaces all current data**.
+
+Restoring is destructive and cannot be undone — reload the integration afterwards so per-child entities refresh. See [Backup and Restore](Backup-and-Restore.md) for full details and cautions.
+
+---
+
+## Custom Time-of-Day Periods (v4.0.0+)
+
+The **Settings → Time-of-day boundaries** section lets you define your own day-part periods instead of the fixed four. You can rename the built-in periods, change their hours and icons, add as many of your own as you like (school run, bedtime, …), or reset to defaults.
+
+- Each period needs a **name**, a **start** and **end** time, and an **icon**.
+- Periods cannot **overlap**; a start must come before its end.
+- A period that is still used by one or more chores **cannot be deleted** until those chores are reassigned — the panel names them.
+- **Anytime** is built-in, all-day, and cannot be removed. Gaps between periods fall back to Anytime.
+- Up to 24 periods are supported. The default four are Morning (06:00–12:00), Afternoon (12:00–17:00), Evening (17:00–21:00), and Night (21:00–23:59).
+
+The label and time inputs render as native fields (v4.0.0, #397) so they work reliably across all Home Assistant versions. A chore's (or card's) `time_category` accepts any period id, plus `anytime` / `all`.
+
+---
+
+## Show IDs (v3.7.0+)
+
+A toggle in the **Settings** tab that displays internal hex IDs on every entity card and row throughout the admin panel. These IDs are needed when writing automations or service calls (e.g. `taskmate.complete_chore` requires a `chore_id`).
+
+### How to use
+
+1. Go to the **Settings** tab in the admin panel
+2. Flip the **Show IDs** toggle
+3. ID badges appear immediately on all entity types:
+
+| Tab | Where |
+|-----|-------|
+| Children | Below child name in card |
+| Chores | Below chore name in row |
+| Rewards | Below reward name in card |
+| Penalties | Below penalty name in card |
+| Bonuses | Below bonus name in card |
+| Groups | Below group name in card |
+
+Each badge shows the full 16-character hex ID with a copy button. Click the copy icon to copy the ID to your clipboard — a "Copied!" toast confirms.
+
+The toggle is stored in your browser's `localStorage` — it's a per-browser preference with no backend change or restart required.
+
+> **Tip:** You may not need to find IDs at all. Since v3.7.0, the HA automation editor shows entity names in dropdown selectors instead of blank text fields for all TaskMate service calls. See [Services — Dynamic Selectors](Services.md#dynamic-selectors-v370).
+
+---
+
+## Real-Time Updates
+
+The admin panel communicates via WebSocket, so changes are reflected immediately without page refreshes. Any changes made in the panel are instantly visible on dashboard cards.
+
+---
+
+## Internationalisation
+
+The admin panel is fully translated in all supported languages:
+
+| Language | Code |
+|----------|------|
+| Danish | `da` |
+| English | `en` |
+| English (GB) | `en-GB` |
+| French | `fr` |
+| German | `de` |
+| Norwegian Bokmål | `nb` |
+| Norwegian Nynorsk | `nn` |
+| Portuguese | `pt` |
+| Portuguese (Brazil) | `pt-BR` |
+
+The panel follows your Home Assistant language setting automatically.
+
+---
+
+## Panel vs Config Flow
+
+> **Changed in v4.0.0:** The options / configure flow has been retired. The admin panel is now the only place to manage TaskMate; only the one-time initial setup uses a config flow. See [Configuration Lives in the Panel](#configuration-lives-in-the-panel-v400) above.
+
+All management — children, chores, rewards, penalties/bonuses, task groups, settings, approvals, timed task config, badge management, notification routing, custom notifications, time-of-day boundaries, audit log, and backup & restore — happens in the admin panel.
+
+---
+
+## Related
+
+- [Getting Started](Getting-Started.md) — initial setup
+- [Setup Wizard](Setup-Wizard.md) — the guided setup with chores suggested by age
+- [Settings](Settings.md) — all configurable settings
+- [Insights](Insights.md) — fairness, friction, week-ahead, health and mood reports
+- [Raffles](Raffles.md), [Help Requests](Help-Requests.md), [Sick Days](Sick-Days.md), [Make-It-Right Penalties](Make-It-Right-Penalties.md) — v7.0.0 features run from the panel
+- [Repairs & Diagnostics](Repairs-and-Diagnostics.md) — setup problems raised in Home Assistant's Settings → Repairs
+- [Printable Weekly Chart](Printable-Weekly-Chart.md) — a fridge-ready A4 chore chart
+- [Template Packs](Template-Packs.md) — export and import shareable chore-template packs
+- [Admin Audit Log](Admin-Audit-Log.md) — who changed what, and when
+- [Backup and Restore](Backup-and-Restore.md) — export / import your setup
+- [Services](Services.md) — the WebSocket API the panel uses internally
diff --git a/wiki/Adult-Profiles.md b/wiki/Adult-Profiles.md
new file mode 100644
index 00000000..92a94c4b
--- /dev/null
+++ b/wiki/Adult-Profiles.md
@@ -0,0 +1,88 @@
+# Adult Profiles
+
+Plenty of parents want to track their own chores too, to set an example or just to keep the house fair. An **adult profile** is a TaskMate profile for a grown-up: their jobs count straight away with no approval, and they stay off the kids' dashboards unless you ask for them.
+
+
+
+> **New in v6.4.0**
+
+---
+
+## Making a Profile an Adult
+
+**TaskMate panel → Children → + Add child** (or **Edit** on an existing profile) → switch on **Adult profile**
+
+
+
+The profile card then carries an **Adult** tag. Everything else about the profile works as it does for a child: chores are assigned the same way, points, levels, streaks and badges all build up, and rewards can be claimed.
+
+You can switch a profile between adult and child at any time.
+
+---
+
+## Chores Count Straight Away
+
+When an adult marks one of their own chores done, it is approved at once and the points are paid, even on a chore that needs approval. Nobody has to sign off a grown-up's washing-up.
+
+- **Photos and notes are still asked for.** If a chore needs [photo proof](Photo-Proof.md), or is [open-ended](Open-Ended-Chores.md) and needs a description, the adult still provides it. It's then approved straight away rather than waiting for review.
+- **Bonus sub-tasks and [timed tasks](Timed-Tasks.md)** are approved straight away too, including a timer that's closed off overnight.
+- **[Teamwork chores](Teamwork-Chores.md) and [bounties](Bounty-Board.md) keep their usual rules.** A team still has to fill up, and a finished bounty still goes to the approval queue.
+- **Children are unchanged.** Their completions still wait for a parent wherever the chore asks for approval.
+
+---
+
+## Adults on the Cards
+
+Kids' dashboards are about the kids, so cards that show the whole family leave adult profiles out by default. A child doesn't need to see Dad at the top of the [leaderboard](Leaderboard-Seasons.md), or Mum's balance in the points list.
+
+To include them, turn on **Show adults** in the card editor, or set it in YAML:
+
+```yaml
+type: custom:taskmate-leaderboard-card
+entity: sensor.taskmate_overview
+show_adults: true
+```
+
+Adults are then listed after the children. The **Show adults** switch only appears in a card's editor once your family has an adult profile, so nothing changes for families without one. On the Chore Board, set it in YAML.
+
+**A card set to one `child_id` is never filtered.** Give an adult a card of their own by pointing it at their profile, exactly as you would for a child.
+
+### Which cards
+
+| Card | Without `show_adults` |
+|------|-----------------------|
+| [Leaderboard](Dashboard-Cards.md#leaderboard-card) | Adults aren't ranked |
+| [Overview](Dashboard-Cards.md#overview-card) | No tile for adults |
+| [Points](Dashboard-Cards.md#points-card) | Adults aren't in the list |
+| [Points Display](Dashboard-Cards.md#points-display-card) | Adults aren't shown |
+| [Points Graph](Dashboard-Cards.md#points-graph-card) | No line for adults |
+| [Streak](Dashboard-Cards.md#streak-card) | Adults aren't shown |
+| [Weekly](Dashboard-Cards.md#weekly-card) | Adults aren't shown |
+| [Calendar](Dashboard-Cards.md#calendar-card) | Adults aren't shown |
+| [Sticker Chart](Sticker-Chart-Card.md) | No chart for adults |
+| [Reward Progress](Dashboard-Cards.md#reward-progress-card) | Adults aren't counted |
+| [Parent Dashboard](Dashboard-Cards.md#parent-dashboard-card) | Adults are left out of the overview and points sections. Approvals and rotation still name everyone |
+| [Kiosk](Kiosk-Mode.md) | Adults aren't on the picker |
+| [Chore Board](Dashboard-Cards.md#chore-board-card) | No column for adults |
+| [Rewards](Dashboard-Cards.md#rewards-card) | No tab for adults, and they're left off a reward's list of children. A [jackpot](Rewards.md) still shows an adult who has put points into it, so the total adds up |
+| [Bonuses](Dashboard-Cards.md#bonuses-card) / [Penalties](Dashboard-Cards.md#penalties-card) | Adults aren't offered when applying one |
+| [Bounty](Dashboard-Cards.md#bounty-card) | Adults aren't shown among who can claim an open bounty |
+
+The **Kiosk** and **Chore Board** cards can also be given a list of children. An adult you pick in that list is always shown; the filter only applies when the card shows everyone.
+
+Cards that belong to one child (the child card, routine, badges, wishlist, recap and auction cards) and the [Approvals card](Approvals-Card.md) aren't affected. The admin panel always shows everyone.
+
+---
+
+## In the Sensors
+
+An adult's entry in `sensor.taskmate_overview`'s `children` list carries `is_adult: true`. The field is left out for children. See [Sensor Attributes](Sensor-Attributes.md#children-entries).
+
+---
+
+## Related
+
+- [Children](Children.md) — adding and managing profiles
+- [Parent Access](Parent-Access.md) — letting a second parent approve and manage day to day
+- [Guest Child Profiles](Guest-Child-Profiles.md) — temporary profiles for visiting children
+- [Dashboard Cards](Dashboard-Cards.md) — every card's options
diff --git a/wiki/Allowance.md b/wiki/Allowance.md
new file mode 100644
index 00000000..5e7d25fe
--- /dev/null
+++ b/wiki/Allowance.md
@@ -0,0 +1,90 @@
+# Allowance
+
+Allowance turns saved-up points into a real-money pocket-money payout. When a child cashes in their points, you record the payout: TaskMate deducts the points and writes a cash entry — in your currency — into a payout ledger you can review later. It is **parent-controlled** and uses a **fixed conversion rate** (no variable or "smart" pricing): a point is always worth the same amount.
+
+
+
+Allowance is **opt-in** and configured in the **TaskMate** panel → **Settings**, in the **Allowance** section of the Admin Panel.
+
+---
+
+## Settings
+
+| Setting | Key | Default | Description |
+|---------|-----|---------|-------------|
+| **Enable allowance payouts** | `allowance_enabled` | `off` | Master toggle. While off, the payout service is rejected |
+| **Points per unit** | `allowance_rate` | `10` | How many points equal one unit of currency. With `10`, 50 points pays out 5 units (e.g. £5.00) |
+| **Currency symbol** | `allowance_currency` | *(blank)* | A short symbol shown against the cash amount, e.g. `£` or `$` (up to 8 characters) |
+
+The rate is a whole number from 1 to 100,000. Leave the toggle off and no payouts can be recorded.
+
+---
+
+## Setting it up
+
+1. Open the **Admin Panel** and scroll to the **Allowance** section
+2. Switch **Enable allowance payouts** on
+3. Set **Points per unit** — the conversion rate. For example, `10` means every 10 points is worth one unit of your currency
+4. Type a **Currency symbol** such as `£` or `$`
+
+The rate is fixed: 50 points is always the same payout. TaskMate never adjusts the conversion based on demand, timing, or balance.
+
+---
+
+## Recording a payout
+
+When a child wants to cash in points — say a weekly Friday pocket-money — record the payout from an automation or a dashboard button using the `record_allowance_payout` service.
+
+```yaml
+# Pay out 50 points as allowance for one child
+service: taskmate.record_allowance_payout
+data:
+ child_id:
+ points: 50
+```
+
+| Parameter | Required | Description |
+|-----------|----------|-------------|
+| `child_id` | ✅ | ID of the child being paid |
+| `points` | ✅ | Points to convert to cash and deduct (1–100,000) |
+
+What happens when it runs:
+
+- The points are **deducted** from the child's balance (logged as `Allowance payout`)
+- A cash amount of `points ÷ rate` (rounded to 2 decimal places) is recorded in the configured currency. With a rate of `10`, paying out `50` points records a payout of `5.00`
+- A ledger entry is stored capturing the child, the points, the cash amount, the currency, and the date
+- A `taskmate_allowance_paid` event is fired — handy for triggering a notification or logging the cash you handed over
+
+The service is **admin-gated** and recorded in the [Admin Audit Log](Admin-Audit-Log.md). It is rejected if allowance is disabled, the child is unknown, or `points` is below 1.
+
+### A weekly payout
+
+To pay out a fixed allowance every Friday, trigger the service on a schedule:
+
+```yaml
+alias: Friday allowance
+triggers:
+ - trigger: time
+ at: "17:00:00"
+ # add a weekday condition for Fridays
+actions:
+ - service: taskmate.record_allowance_payout
+ data:
+ child_id:
+ points: 50
+```
+
+---
+
+## The payout ledger
+
+Every recorded payout is appended to a ledger stored as `allowance_payouts` (capped at the most recent 500 entries). The **Allowance** section of the Admin Panel lists the most recent payouts — child, cash amount, and date — so you have a running record of what has been paid out. There is no separate ledger sensor; the history is surfaced in the panel.
+
+---
+
+## Related
+
+- [Points Economy](Points-Economy.md) — interest, decay, and the negative-balance policy
+- [Rewards](Rewards.md) — spending points on in-app rewards instead of cash
+- [Admin Audit Log](Admin-Audit-Log.md) — who recorded which payout
+- [Services](Services.md) — full service-call reference
diff --git a/wiki/Approvals-Card.md b/wiki/Approvals-Card.md
new file mode 100644
index 00000000..5d91e077
--- /dev/null
+++ b/wiki/Approvals-Card.md
@@ -0,0 +1,124 @@
+# Approvals Card
+
+The TaskMate Approvals Card shows every pending action that needs a parent's sign-off — completed chores waiting for approval and, from v3.0, reward claims waiting for approval.
+
+## Adding the card
+
+**Edit dashboard → + Add Card → Custom: TaskMate Approvals Card**
+
+Or via YAML:
+
+```yaml
+type: custom:taskmate-approvals-card
+entity: sensor.taskmate_overview
+```
+
+The card works with either:
+- `sensor.taskmate_overview` (reads `todays_completions` filtered to unapproved + `pending_reward_claims`)
+- `sensor.taskmate_pending_approvals` (reads `chore_completions` + `reward_claims`)
+
+## Configuration
+
+| Option | Type | Default | Description |
+| --- | --- | --- | --- |
+| `entity` | string | **required** | TaskMate overview or pending_approvals sensor |
+| `title` | string | `"Pending Approvals"` | Card header title |
+| `child_id` | string | _none_ | If set, filter approvals to this child only |
+| `header_color` | string | `#27ae60` | Card header background colour |
+
+## Display
+
+### Header
+- Title on the left
+- Combined **pending count** badge on the right (chores + reward claims)
+
+### Mandatory — needs review (v4.1+)
+If any mandatory chores were missed, they appear at the very top of the content — above pending completions — under a header labelled **"Mandatory — needs review"**. A mandatory chore is missed when it isn't completed before its time-of-day period ends; **points are never auto-deducted**, the parent decides what to do. Each row offers three actions:
+
+- **Apply Penalty** — calls `taskmate.apply_mandatory_penalty`, deducting the chore's configured penalty points. The Apply-penalty button only appears when those points are greater than 0.
+- **Postpone** — calls `taskmate.postpone_mandatory_chore`, giving the chore the next period today (rolling to tomorrow after the last period). Repeatable, no penalty.
+- **Dismiss** — calls `taskmate.dismiss_mandatory_chore`, clearing the review item with no penalty.
+
+Each service takes a single `miss_id` parameter. See [Mandatory Chores](Mandatory-Chores.md) for the full feature.
+
+
+
+### Reward claims section (v3.0+)
+If any reward claims are pending, they appear at the top of the content, under a header labelled **"Reward claims"**. Each row shows:
+- Red ✗ button (reject) on the left
+- Reward icon + name
+- Child name
+- Points cost
+- Green ✓ button (approve) on the right
+
+Tapping ✓ calls `taskmate.approve_reward`. Tapping ✗ calls `taskmate.reject_reward`.
+
+### Chore approvals section
+Chores awaiting approval appear below, grouped by **day** (Today, Yesterday, or the date) and by **time category** within each day. Each row has the same approve / reject UX.
+
+Tapping ✓ calls `taskmate.approve_chore`. Tapping ✗ calls `taskmate.reject_chore`.
+
+Completions that require photo proof show an **evidence-photo thumbnail** on the row; tapping it opens the full image.
+
+### Reference photo compare (v7.0.0)
+When the chore has a [reference photo](Reference-Photos.md) (a picture of the job done well), the row also shows it as a thumbnail with a ★ badge. Tapping either picture opens them side by side, **What good looks like** next to **What was done**, so you can compare before approving. If the child sent no photo, the reference shows on its own with a reminder to compare it with the real thing. The review sheet shows the same side-by-side view. The [Parent Dashboard card](Dashboard-Cards.md#parent-dashboard-card) shows the reference thumbnail too.
+
+### Quantity chores (v7.0.0)
+A [quantity chore](Quantity-Chores.md) shows how many units the child said they did (e.g. "🔢 12 pages") on the row's details and in the review sheet, so you can see what is being paid for. Chores still waiting after the [auto-approve](Auto-Approve.md) timeout approve themselves and leave the queue.
+
+### Review and award (v5.7.0+)
+Every chore row carries a second control beside Approve — **✍️** when the child left a description, **✎** otherwise. It opens a review sheet with the child's words, the evidence photo if there is one, and an **Award** box you can edit before approving.
+
+The award replaces the chore's *base* points, so streaks and level multipliers still apply on top exactly as they would for a normal approval. Tapping Approve on the row itself is unchanged — still one tap, still the chore's own points.
+
+This is how an [open-ended chore](Open-Ended-Chores.md) gets priced, but it works on any pending completion.
+
+### Approve All (v4.4.3+)
+When two or more chore completions are pending, an **Approve All** button appears in the chore-approvals section so you can clear the whole queue in one tap instead of approving each row. It calls the `taskmate/approve_all_chores` WebSocket command, which approves every currently-pending completion and runs the full award/badge/quest/streak/celebration side-effects on each — identical to approving them one by one. The same button is also available on the TaskMate panel's pending-approvals view. Reward claims and mandatory-review items are unaffected; you still action those individually.
+
+While the batch runs, the button is disabled and shows a spinner with **Approving…**, on both the card and the panel. A second tap is ignored, so you cannot queue the same sweep twice.
+
+### Empty state
+When nothing is pending, the card shows *"All caught up!"* with a check icon.
+
+## Notifications (v3.0+)
+
+When a child completes a chore or claims/redeems a reward, TaskMate fires:
+
+- A `persistent_notification` with a descriptive message — *"{child} claimed '{reward}' ({cost} {points_name}) and is waiting for your approval."*
+- The configured `notify.*` service, if one is set in TaskMate settings (e.g. a mobile notification)
+
+This applies to both wallet-mode claims and pool-mode Redeems, putting them on parity with chore approvals.
+
+## Examples
+
+### Show approvals for everybody
+
+```yaml
+type: custom:taskmate-approvals-card
+entity: sensor.taskmate_overview
+```
+
+### Filter to one child
+
+```yaml
+type: custom:taskmate-approvals-card
+entity: sensor.taskmate_overview
+child_id: 8a3b2c1d4e5f6789
+title: "Alice's Approvals"
+```
+
+### Custom header colour
+
+```yaml
+type: custom:taskmate-approvals-card
+entity: sensor.taskmate_overview
+header_color: "#3498db"
+```
+
+## Related
+
+- [Services](Services.md) — `approve_chore`, `approve_all_chores`, `reject_chore`, `approve_reward`, `reject_reward`, `apply_mandatory_penalty`, `postpone_mandatory_chore`, `dismiss_mandatory_chore`
+- [Mandatory Chores](Mandatory-Chores.md) — the "Mandatory — needs review" section explained
+- [Quality Ratings](Quality-Ratings.md) — rate approved chores 1–3 stars and scale the points
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — context for pool-mode Redeem claims
diff --git a/wiki/Auto-Approve.md b/wiki/Auto-Approve.md
new file mode 100644
index 00000000..07dbc024
--- /dev/null
+++ b/wiki/Auto-Approve.md
@@ -0,0 +1,71 @@
+# Auto Approve
+
+A parent on a 12-hour shift can't approve "Make bed" before the child wants to know whether it counted. With **auto-approve**, a chore that has waited for approval longer than a set number of hours approves itself at the points the child was promised, exactly as if you had tapped Approve.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Turning It On
+
+**TaskMate panel → Settings → Auto-approve after (hours)** (with the other parent approval settings)
+
+| Setting | Key | Default | Description |
+|---------|-----|---------|-------------|
+| **Auto-approve after (hours)** | `auto_approve_hours` | `0` | Chores still waiting this long approve themselves. Whole hours, 1–168 (a week). 0 = off |
+
+TaskMate checks once a minute, so a completion approves itself within a minute of reaching the limit. The clock starts when the child completed the chore.
+
+---
+
+## What Gets Approved
+
+Any chore completion still waiting for approval, once it's older than the limit. It's approved exactly as a parent's tap would: the promised points are paid, and streaks, badges, challenges, quests, [weekly goals](Weekly-Goals.md) and a waiting [make-it-right](Make-It-Right-Penalties.md) refund all follow as normal.
+
+Two kinds always wait for you, however long it takes:
+
+| Never auto-approved | Why |
+|---------------------|-----|
+| [Open-ended chores](Open-Ended-Chores.md) | The child only suggested a price; a parent has to set the real one |
+| [Bounty](Bounty-Board.md) work | A bounty pays its own posted reward and has its own claim rules |
+
+Reward claims are not affected: only chore completions auto-approve.
+
+If an approval fails for some reason (for example the chore has since been deleted), that completion is skipped and stays waiting.
+
+---
+
+## Knowing It Happened
+
+Each auto-approval:
+
+- marks the completion with `auto_approved: true`, so it can be told apart from one a parent approved
+- fires the `taskmate_chore_auto_approved` event, with `child_id`, `child_name`, `chore_id`, `chore_name`, `points` and `hours` (the setting at the time)
+- shows as **Chore auto-approved** on the child's [event entity](Event-Entities.md)
+
+A notification for it is easy to build from the event:
+
+```yaml
+triggers:
+ - trigger: event
+ event_type: taskmate_chore_auto_approved
+actions:
+ - action: notify.mobile_app_parent_phone
+ data:
+ message: >-
+ {{ trigger.event.data.chore_name }} for {{ trigger.event.data.child_name }}
+ was approved automatically after {{ trigger.event.data.hours }} hours.
+```
+
+You can still undo an auto-approved chore from the activity list, as with any approval.
+
+---
+
+## Related
+
+- [Approvals Card](Approvals-Card.md) — approving chores yourself
+- [Multi-Parent Approval Routing](Multi-Parent-Approval-Routing.md) — sending approvals to the right parent
+- [Parent Access](Parent-Access.md) — letting other adults approve
+- [Automations](Automations.md) — every TaskMate event
diff --git a/wiki/Automations.md b/wiki/Automations.md
new file mode 100644
index 00000000..00d023e8
--- /dev/null
+++ b/wiki/Automations.md
@@ -0,0 +1,637 @@
+# Automations
+
+Examples of useful automations using TaskMate sensors and services.
+
+---
+
+## Internal Scheduled Tasks
+
+TaskMate runs several automatic tasks on a schedule. These are **not** HA automations — they run inside the integration.
+
+### Midnight tasks (00:00:05)
+
+| Task | Description |
+|------|-------------|
+| **Streak check** | Updates each child's streak. In `reset` mode: missed days reset the streak to 0. In `pause` mode: missed days freeze the streak until the next completion. |
+| **One-shot chore expiry** | Disables any one-shot chores created on the previous day. |
+| **Assignment rotation** | Recomputes `assignment_current_child_id` for chores using `alternating`, `random`, or `balanced` modes. Task group policies (sticky/spread) are applied after raw picks. |
+| **Calendar publishing** | Publishes chore assignment events to configured HA calendar entities, projected ahead by the configured number of days. Uses configurable time-of-day boundaries (v3.6.0+). |
+| **Perfect week check** | Runs on **Mondays only**. Awards the perfect week bonus to any child who completed at least one chore every day the previous week (Mon–Sun). |
+| **Stale timed session cleanup** | Stops any timed task sessions left running from previous days. Creates completion records with elapsed time up to midnight. |
+| **Career score snapshot** | Saves each child's career score for historical tracking. Prunes snapshots older than 90 days. |
+| **Skip state reset** | Clears ephemeral skip data (`skip_date`, `skip_count`) from the previous day. |
+
+### History pruning (00:01:00)
+
+Trims old completion records to the configured **History Days** setting (default: 90 days, range: 30–365).
+
+### Availability monitoring (real-time)
+
+TaskMate listens for `state_changed` events on all entities configured as a child's **Availability Entity**. When a tracked entity changes state:
+
+1. TaskMate re-evaluates which children are available
+2. Chores with **Require Availability** enabled recompute their assignments
+3. Unavailable children are skipped in `alternating`, `random`, and `balanced` rotation
+
+**Recognised "available" states:** `on`, `home`, `available`, `present`, `true`. Any other state (including `unavailable`, `off`, `unknown`) is treated as unavailable.
+
+### Assignment rotation algorithms
+
+| Mode | Algorithm |
+|------|-----------|
+| `alternating` | Round-robin using `(today - anchor_date) mod pool_size` to pick the child index |
+| `random` | Deterministic daily pick using `SHA256(chore_id + date)` — stable within a day, changes at midnight |
+| `balanced` | Groups all balanced-mode chores sharing the same child pool, sorts by ID, and distributes evenly via round-robin so no child gets more than one extra chore |
+
+### Task group assignment
+
+After raw per-chore rotation picks are calculated:
+
+1. **Sticky groups:** The first chore (leader) keeps its pick. All followers are forced onto the leader's child, provided that child is in their pool. If not, followers fall back to their own pick.
+2. **Spread groups:** Each chore is assigned a different child. The algorithm walks forward from each chore's raw pick to find an unused child, wrapping if more chores than children.
+
+### Calendar event format
+
+When chores are published to a calendar, the events look like this:
+
+- **Title:** `Wash Dishes — Tommy` (chore name + assigned child)
+- **Time-based chores** create timed events matching the time category:
+
+| Time category | Event window |
+|---------------|-------------|
+| `morning` | 06:00–12:00 |
+| `afternoon` | 12:00–17:00 |
+| `evening` | 17:00–21:00 |
+| `night` | 21:00–23:59 |
+| `anytime` | All-day event |
+
+- **Description** contains an internal marker (`taskmate:chore:`) used for cleanup — do not edit it manually
+- Events are only published for dates not already in the calendar (idempotent)
+- When a chore is deleted or edited, old calendar events are automatically cleaned up
+
+### Automatic reward expiry & refunds
+
+At midnight, rewards past their **expiration date** are marked expired. Pool allocations for expired rewards are **automatically refunded** to each child's spendable balance. The same refund logic runs when a reward's cost is reduced below a child's current allocation.
+
+### Timed task auto-stop
+
+Stale timed sessions (sessions from a previous day still in `running` or `paused` state) are automatically stopped at midnight. A completion record is created using the elapsed time accumulated up to that point. This prevents children from accidentally leaving timers running overnight.
+
+---
+
+## Bus Events Reference
+
+TaskMate fires Home Assistant bus events for most state changes. Trigger your own automations off them with an `event` trigger. Every event carries a `timestamp` (ISO 8601) unless noted, and most carry `child_id` / `child_name`.
+
+### Points, rewards & penalties
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_penalty_applied` | `child_id`, `child_name`, `penalty_id`, `penalty_name`, `points`, `timestamp` |
+| `taskmate_bonus_applied` | `child_id`, `child_name`, `bonus_id`, `bonus_name`, `points`, `timestamp` |
+| `taskmate_points_gifted` | `from_child_id`, `from_child_name`, `to_child_id`, `to_child_name`, `points`, `timestamp` |
+| `taskmate_points_decay` | `child_id`, `child_name`, `points`, `timestamp` |
+| `taskmate_interest_paid` | `child_id`, `child_name`, `points`, `timestamp` |
+| `taskmate_surprise_bonus` | `child_id`, `child_name`, `points`, `timestamp` |
+| `taskmate_perfect_week` | `child_id`, `week_key`, `bonus`, `timestamp` |
+
+### Chores
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_chore_completed` | `child_id`, `child_name`, `chore_id`, `chore_name`, `points`, `difficulty`, `timestamp` |
+| `taskmate_chore_approved` | `child_id`, `chore_id`, `completion_id`, `timestamp` |
+| `taskmate_chore_rejected` | `child_id`, `child_name`, `chore_id`, `chore_name`, `completion_id`, `reason` (v6.0.0, empty when none was given), `timestamp` |
+| `taskmate_swap_approved` | `chore_id`, `requester_id`, `from_child_id`, `timestamp` |
+| `taskmate_weekly_target_reached` | `child_id`, `child_name`, `chore_id`, `chore_name`, `target`, `bonus`, `timestamp` — (v6.2.0) a child's approved completions reached a chore's [weekly target](Weekly-Targets.md#weekly-target-bonus) and the bonus was paid. Only fires on chores with a bonus set, once per child, chore and week |
+
+### Rewards
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_reward_claimed` | `child_id`, `reward_id`, `claim_id`, `cost`, `timestamp` |
+| `taskmate_reward_approved` | `child_id`, `child_name`, `reward_id`, `reward_name`, `claim_id`, `cost`, `timestamp` |
+| `taskmate_reward_rejected` | `child_id`, `child_name`, `reward_id`, `reward_name`, `claim_id`, `reason` (v6.0.0), `timestamp` |
+
+`claim_id` is the same across all three reward events, so a claim can be followed from request to outcome — see [External Lock-Screen Shops](External-Lock-Screen-Shops.md). Since v6.0.0, redeeming a [wish](Wishlist.md) runs through these same events, with an extra `wish_id`.
+
+### Streaks, badges & gamification
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_streak_updated` | `child_id`, `current_streak`, `best_streak`, `timestamp` |
+| `taskmate_badge_earned` | `child_id`, `badge_id`, `awarded_id`, `name`, `icon`, `tier` |
+| `taskmate_level_up` | `child_id`, `child_name`, `level`, `timestamp` |
+| `taskmate_celebration` | `child_id`, `child_name`, `kind`, `tier` (1–3), `message`, `timestamp` (+ event-specific extras, e.g. `level`) |
+| `taskmate_quest_completed` | `child_id`, `child_name`, `quest_id`, `quest_name`, `bonus`, `timestamp` |
+| `taskmate_challenge_completed` | `child_id`, `child_name`, `challenge_id`, `challenge_name`, `scope`, `bonus`, `timestamp` |
+
+### Mandatory chores
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_mandatory_missed` | `miss_id`, `chore_id`, `child_id`, `period_id`, `penalty_points`, `timestamp` |
+| `taskmate_mandatory_penalty_applied` | `miss_id`, `chore_id`, `child_id`, `points`, `timestamp` |
+| `taskmate_mandatory_postponed` | `miss_id`, `chore_id`, `child_id`, `next_period`, `timestamp` |
+| `taskmate_mandatory_dismissed` | `miss_id`, `chore_id`, `child_id`, `timestamp` |
+
+### Allowance, goals & seasons
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_allowance_paid` | `child_id`, `child_name`, `points`, `month`, `timestamp` |
+| `taskmate_family_goal_reached` | `goal_name`, `goal_reward`, `target`, `timestamp` |
+| `taskmate_season_champion` | `month`, `child_id`, `child_name`, `points`, `timestamp` |
+
+### Undo
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_chore_approval_undone` | `child_id`, `child_name`, `chore_id`, `chore_name`, `completion_id`, `timestamp` |
+
+### v5.0.0 events
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_chore_expired` | `chore_id`, `chore_name`, `deadline_at`, `timestamp` — a [reactive chore](Reactive-Chores.md) passed its deadline |
+| `taskmate_roulette_spun` | `child_id`, `child_name`, `chore_id`, `chore_name`, `multiplier`, `timestamp` — see [Chore Roulette](Chore-Roulette.md) |
+| `taskmate_unlock_started` | `entity_id`, `reward_id`, `reward_name`, `child_id`, `child_name`, `started_at`, `revert_at` — see [Timed Unlock Rewards](Timed-Unlock-Rewards.md) |
+| `taskmate_unlock_ended` | same fields as `taskmate_unlock_started`, fired when the timer reverts the entity |
+| `taskmate_scheduled_change_applied` | `change_id`, `chore_id`, `chore_name`, `changes`, `timestamp` — see [Scheduled Config Changes](Scheduled-Config-Changes.md) |
+| `taskmate_guest_archived` | `child_id`, `child_name`, `expired_on`, `timestamp` — see [Guest Child Profiles](Guest-Child-Profiles.md) |
+| `taskmate_read_aloud` | `child_id`, `media_player`, `tts_entity`, `message` — see [Read Aloud](Read-Aloud.md) |
+
+### v6.0.0 events
+
+Grouped the same way as the release notes. Every event carries a `timestamp` unless noted.
+
+**Chores and streaks**
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_tag_completion` | `tag_id`, `device_id`, `child_id`, `child_name`, `chore_id`, `chore_name`, `completion_id`, `pending_approval` (no `timestamp`) — a chore was completed by scanning an [NFC tag or QR code](NFC-Tag-Completion.md) |
+| `taskmate_team_chore_joined` | `child_id`, `child_name`, `chore_id`, `chore_name`, `joined`, `team_size` (no `timestamp`) — a child joined a [teamwork chore](Teamwork-Chores.md) that isn't full yet |
+| `taskmate_team_chore_completed` | `chore_id`, `chore_name`, `child_ids`, `team_size` (no `timestamp`) — the team filled up and everyone got a completion |
+| `taskmate_chore_undone` | `child_id`, `child_name`, `chore_id`, `chore_name`, `completion_id`, `timestamp` — a child took back their own chore inside the [undo window](Child-Undo-Window.md) (a parent's rejection fires `taskmate_chore_rejected` instead) |
+| `taskmate_streak_freeze_used` | `child_id`, `child_name`, `date`, `streak`, `freezes_left`, `timestamp` — a [streak freeze](Streak-Freezes.md) token saved the streak on `date` |
+
+**Recaps**
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_recap_ready` | `child_id`, `child_name`, `count`, `recaps`, `recipients` (no `timestamp`) — one per child when new [recaps](Recaps.md) are announced at the send time. Fires even when the Recap ready notification is off |
+
+**Bounties** — see [Bounty Board](Bounty-Board.md)
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_bounty_posted` | `bounty_id`, `title`, `points` (no `timestamp`) |
+| `taskmate_bounty_updated` | `bounty_id`, `title`, `points`, `claimed_by` (no `timestamp`) |
+| `taskmate_bounty_removed` | `bounty_id`, `title` (no `timestamp`) |
+| `taskmate_bounty_claimed` | `bounty_id`, `title`, `points`, `child_id`, `child_name`, `timestamp` — a child claimed it |
+| `taskmate_bounty_given_back` | same fields — the child handed it back to the board |
+| `taskmate_bounty_released` | same fields — a parent put a claimed bounty back on the board |
+| `taskmate_bounty_claim_lapsed` | same fields — the claim ran out before the job was finished |
+| `taskmate_bounty_completed` | same fields — the child marked it done; it is now waiting for approval |
+| `taskmate_bounty_approved` | same fields — a parent approved the finished job |
+| `taskmate_bounty_rejected` | same fields — a parent rejected it; the bounty goes back to the same child |
+| `taskmate_bounty_withdrawn` | same fields — the child took back their submission |
+| `taskmate_bounty_expired` | same fields (empty `child_id`) — an unclaimed bounty passed its expiry |
+
+A finished bounty also fires the usual `taskmate_chore_completed`, with the bounty ID as `chore_id` and an extra `bounty_id`.
+
+**Wishes** — see [Wishlist](Wishlist.md)
+
+All wish events carry `wish_id`, `wish_name`, `child_id`, `child_name`, `target`, `saved`, `pledged` and `timestamp`.
+
+| Event | Extra fields / when |
+|-------|---------------------|
+| `taskmate_wish_added` | A child added a wish |
+| `taskmate_wish_approved` | A parent approved it as a savings goal |
+| `taskmate_wish_declined` | A parent declined it |
+| `taskmate_wish_pledged` | `points`, `pledger` — someone pledged points towards it |
+| `taskmate_wish_saved` | `points` — the child moved points into it |
+
+**Inspections** — see [Surprise Inspections](Surprise-Inspections.md)
+
+All inspection events carry `inspection_id`, `completion_id`, `child_id`, `child_name`, `chore_id`, `chore_name`, `bonus`, `status` and `timestamp`.
+
+| Event | Extra fields / when |
+|-------|---------------------|
+| `taskmate_inspection_started` | A parent (or the daily pick) started one |
+| `taskmate_inspection_passed` | It passed and the bonus was paid |
+| `taskmate_inspection_failed` | `redo` — it didn't pass; `redo` is `true` when the chore was sent back |
+| `taskmate_inspection_expired` | Nobody decided before the window closed |
+| `taskmate_inspection_cancelled` | A parent called it off |
+| `taskmate_inspection_reopened` | A pass bonus was undone while the window was still open, so the inspection is open again |
+
+**Auctions** — see [Chore Auctions](Chore-Auctions.md)
+
+All auction events carry `auction_id`, `chore_id`, `chore_name`, `occurrence` (the chore's date), `max_points`, `bid_count`, `child_id`, `child_name` and `timestamp`. They **never** include what anyone bid.
+
+| Event | Extra fields / when |
+|-------|---------------------|
+| `taskmate_auction_opened` | An auction opened (`child_id` empty) |
+| `taskmate_auction_bid` | A child placed or changed a bid |
+| `taskmate_auction_bid_withdrawn` | A child withdrew their bid |
+| `taskmate_auction_closed` | `price` — bidding closed; `child_id` is the winner (empty when nobody bid) and `price` the winning price |
+| `taskmate_auction_cancelled` | The auction was cancelled (`child_id` empty) |
+
+> Since v6.1.0 each of these events fires once. When the matching notification is also sent, the notification system fires a separate `taskmate__notification` event (e.g. `taskmate_bounty_posted_notification`) carrying the `recipients` list. See [Notifications](Notifications.md#bus-events).
+
+> Notification-type events (`taskmate_pending_chore_approval`, `taskmate_badge_earned_notification`, `taskmate_weekly_digest`, …) carry an extra `recipients` list and are documented in [Notifications](Notifications.md#bus-events).
+
+### v7.0.0 events
+
+| Event | Data fields |
+|-------|-------------|
+| `taskmate_chore_auto_approved` | `child_id`, `child_name`, `chore_id`, `chore_name`, `points`, `hours`, `timestamp` — a chore nobody reviewed within `hours` approved itself. See [Auto-Approve](Auto-Approve.md). The usual `taskmate_chore_approved` fires as well |
+| `taskmate_help_requested` | `child_id`, `child_name`, `chore_id`, `chore_name`, `message`, `message_text`, `request_id`, `recipients` (no `timestamp`) — a child tapped "I'm stuck". Pass `request_id` to `taskmate.answer_help`. See [Help Requests](Help-Requests.md) |
+| `taskmate_mood_logged` | `child_id`, `child_name`, `mood`, `emoji`, `timestamp` — a child did the end-of-day [mood check-in](Mood-Check-In.md). `mood` is `great`, `good`, `ok`, `sad` or `upset` |
+| `taskmate_mood_low` | `child_id`, `child_name`, `mood`, `emoji`, `recipients` (no `timestamp`) — the mood was `sad` or `upset` |
+| `taskmate_sick_day` | `child_id`, `child_name`, `date`, `sick`, `timestamp` — a [sick day](Sick-Days.md) was given (`sick: true`) or taken back (`sick: false`) |
+| `taskmate_weekly_goal_reached` | `child_id`, `child_name`, `target`, `earned`, `bonus`, `points_name`, `recipients` (no `timestamp`) — a child reached their [weekly goal](Weekly-Goals.md) |
+| `taskmate_penalty_redeemed` | `child_id`, `child_name`, `penalty_name`, `chore_name`, `points`, `points_name`, `recipients` (no `timestamp`) — a child did the [make-it-right](Make-It-Right-Penalties.md) chore and earned `points` back |
+| `taskmate_raffle_won` | `child_id`, `child_name`, `raffle_id`, `raffle_name`, `prize`, `tickets`, `timestamp` — the winner of a [raffle](Raffles.md); `tickets` is how many they held |
+| `taskmate_raffle_drawn` | `raffle_id`, `raffle_name`, `prize`, `winner_id`, `winner_name`, `tickets`, `recipients` (no `timestamp`) — a raffle was drawn; `tickets` is the total in the draw. Fires even when nobody entered (`winner_id` empty) |
+| `taskmate_pet_evolved` | `child_id`, `child_name`, `pet_name`, `species`, `kind`, `news`, `recipients` (no `timestamp`), plus `pet_level` when `kind` is `level` — a [virtual pet](Virtual-Pets.md) reached something new. `kind` is `stage`, `legendary`, `egg` or `level`; `news` is the ready-made sentence |
+
+The events with a `recipients` list come from the notification system and fire whether or not the matching notification is switched on (`recipients` is then empty). See [Notifications](Notifications.md#bus-events).
+
+#### Event entities
+
+Since v7.0.0 the same moments are also published as **event entities**: one per child (`event.taskmate__activity`) and one for the family (`event.taskmate_family_activity`). They make TaskMate moments pickable in the UI automation editor without typing an event name ("When Malia's activity has event type chore_approved"), and show the latest moment on a dashboard. See [Event Entities](Event-Entities.md).
+
+### Example — react to a celebration with lights
+
+The `taskmate_celebration` event carries a `tier` (1 = small, 2 = medium, 3 = epic) so a single automation can scale its reaction to the size of the moment.
+
+```yaml
+alias: TaskMate — Celebrate big moments
+triggers:
+ - trigger: event
+ event_type: taskmate_celebration
+conditions:
+ - condition: template
+ value_template: "{{ trigger.event.data.tier >= 3 }}"
+actions:
+ - action: light.turn_on
+ target:
+ entity_id: light.living_room
+ data:
+ effect: rainbow
+ - action: notify.mobile_app_johns_phone
+ data:
+ title: "🎉 TaskMate"
+ message: "{{ trigger.event.data.message }}"
+```
+
+### Example — log every penalty
+
+```yaml
+alias: TaskMate — Log penalties
+triggers:
+ - trigger: event
+ event_type: taskmate_penalty_applied
+actions:
+ - action: logbook.log
+ data:
+ name: TaskMate
+ message: >
+ {{ trigger.event.data.child_name }} lost
+ {{ trigger.event.data.points }} for "{{ trigger.event.data.penalty_name }}"
+```
+
+---
+
+## Blueprint Pack
+
+TaskMate ships a set of ready-made Home Assistant **automation blueprints** so you can react to the most common TaskMate moments without writing the trigger and condition logic yourself. Each blueprint fires on a TaskMate bus event and lets you pick the action to run — flash a light, play a sound, announce on a speaker, run a scene, send a notification, and so on.
+
+| Blueprint | Fires on | Use it for | Inputs |
+|-----------|----------|-----------|--------|
+| `chore_completed.yaml` | `taskmate_chore_completed` | Reward a completed chore — flash a light, play a chime, post a message | **Only this child** (optional name to restrict to one child; blank = all) and your **Action** |
+| `level_up.yaml` | `taskmate_level_up` | Celebrate when a child reaches a new XP level | **Only this child** (optional) and your **Action** |
+| `reward_approved.yaml` | `taskmate_reward_approved` | React when a reward claim is approved — announce it, unlock a smart plug for the games console | **Only this child** (optional) and your **Action** |
+| `mandatory_missed.yaml` | `taskmate_mandatory_missed` | React when a mandatory chore's time window closes incomplete — pause the TV, turn a light red, alert a parent | Your **Action** (fires for every child) |
+
+The first three accept an optional **Only this child** name: leave it blank to react to every child, or enter a child's exact name to restrict the automation to them. `mandatory_missed` has no child filter — it runs for any missed mandatory chore. (For more control, you can still build your own automation off these events directly — see [Bus Events Reference](#bus-events-reference) above.)
+
+### Importing a blueprint
+
+In Home Assistant, go to **Settings → Automations & scenes → Blueprints → Import blueprint**, then paste the raw URL of the blueprint you want, for example:
+
+```
+https://github.com/tempus2016/taskmate/blob/main/blueprints/automation/taskmate/chore_completed.yaml
+```
+
+Then choose **Create automation → (the imported blueprint)**, optionally set the child name, and pick your action.
+
+### Event data in your action
+
+The triggering event is available to your action's templates as `trigger.event.data`:
+
+| Blueprint event | Available fields |
+|-----------------|------------------|
+| `taskmate_chore_completed` | `child_name`, `chore_name`, `points`, `difficulty` |
+| `taskmate_level_up` | `child_name`, `level` |
+| `taskmate_reward_approved` | `child_name`, `reward_name`, `cost` |
+| `taskmate_mandatory_missed` | `child_id`, `chore_id`, `period_id`, `penalty_points` |
+
+For example, an action that announces who finished what:
+
+```yaml
+service: notify.mobile_app_johns_phone
+data:
+ message: "{{ trigger.event.data.child_name }} finished {{ trigger.event.data.chore_name }}!"
+```
+
+---
+
+## Example Automations
+
+---
+
+## Notify Parents When Approvals Are Pending
+
+> **Note:** TaskMate v1.1.3+ has built-in notification support. Configure a notify service in the **TaskMate** panel → **Notifications** for simple per-chore alerts. Use the automation below for more control — multiple recipients, conditions, custom messages, scheduling.
+
+Send a push notification to the parent's phone when a chore is waiting for approval.
+
+```yaml
+alias: TaskMate — Notify on pending approval
+trigger:
+ - platform: state
+ entity_id: binary_sensor.taskmate_has_pending_approvals
+ to: "on"
+action:
+ - service: notify.mobile_app_johns_phone
+ data:
+ title: "TaskMate ✅"
+ message: >
+ {{ state_attr('binary_sensor.taskmate_has_pending_approvals', 'pending_chore_completions') }}
+ chore(s) and
+ {{ state_attr('binary_sensor.taskmate_has_pending_approvals', 'pending_reward_claims') }}
+ reward claim(s) awaiting approval.
+ data:
+ url: /lovelace/parent-dashboard
+```
+
+---
+
+## Remind Child to Complete Chores
+
+Send a reminder if a child hasn't completed any chores by a certain time.
+
+```yaml
+alias: TaskMate — Evening chore reminder
+trigger:
+ - platform: time
+ at: "18:00:00"
+condition:
+ - condition: template
+ value_template: >
+ {% set children = state_attr('sensor.taskmate_overview', 'children') %}
+ {% set child = children | selectattr('name', 'eq', 'Malia') | first %}
+ {{ child.pending_points == 0 and child.points == child.points }}
+ {# Simpler: check if done_today from todays_completions #}
+action:
+ - service: notify.mobile_app_malias_tablet
+ data:
+ title: "Don't forget your chores! 🌟"
+ message: "You still have chores to do today. Check your chore list!"
+```
+
+---
+
+## Award Bonus Points for Good Behaviour
+
+Use an input_button or a script to quickly award bonus points.
+
+```yaml
+# input_button.yaml
+input_button:
+ malia_bonus:
+ name: "Award Malia Bonus Points"
+ icon: mdi:star-plus
+
+# automation.yaml
+alias: TaskMate — Award bonus on button press
+trigger:
+ - platform: state
+ entity_id: input_button.malia_bonus
+action:
+ - service: taskmate.add_points
+ data:
+ child_id: a8c8376a
+ points: 5
+ reason: "Good behaviour bonus"
+```
+
+---
+
+## Weekly Summary Notification
+
+Send a weekly summary of each child's activity every Sunday evening.
+
+```yaml
+alias: TaskMate — Weekly summary
+trigger:
+ - platform: time
+ at: "19:00:00"
+condition:
+ - condition: time
+ weekday:
+ - sun
+action:
+ - service: notify.mobile_app_johns_phone
+ data:
+ title: "TaskMate Weekly Summary 📊"
+ message: >
+ {% set children = state_attr('sensor.taskmate_overview', 'children') %}
+ {% for child in children %}
+ {{ child.name }}: {{ child.points }} pts | {{ child.current_streak }} day streak
+ {% endfor %}
+```
+
+---
+
+## Complete a Chore via NFC Tag
+
+> **Since v6.0.0 this is built in.** Link tags to a chore in the chore editor under **More options → NFC / QR tags**, and TaskMate works out which child scanned. See [NFC Tag Completion](NFC-Tag-Completion.md). The automation below is still useful if you want to do something extra on a scan, such as sending a message.
+
+Tap an NFC tag to automatically complete a chore without opening the app.
+
+```yaml
+alias: TaskMate — NFC complete Make Bed
+trigger:
+ - platform: tag
+ tag_id: "your-nfc-tag-id-here"
+action:
+ - service: taskmate.complete_chore
+ data:
+ chore_id: b3f9a12c
+ child_id: a8c8376a
+ - service: notify.mobile_app_malias_tablet
+ data:
+ title: "Chore completed! ⭐"
+ message: "Make Bed marked as done. +5 Stars!"
+```
+
+---
+
+## Complete a Chore When a Smart Device is Used
+
+Use a smart plug or presence sensor to automatically complete a chore.
+
+**Example: Brushing teeth — complete when bathroom motion detected at the right time:**
+
+```yaml
+alias: TaskMate — Auto complete brush teeth
+trigger:
+ - platform: state
+ entity_id: binary_sensor.bathroom_motion
+ to: "on"
+condition:
+ - condition: time
+ after: "07:00:00"
+ before: "08:30:00"
+ - condition: time
+ weekday:
+ - mon
+ - tue
+ - wed
+ - thu
+ - fri
+action:
+ - service: taskmate.complete_chore
+ data:
+ chore_id: brush_teeth_chore_id
+ child_id: a8c8376a
+```
+
+---
+
+## Daily Streak Reminder
+
+Remind a child if they haven't completed a chore today and their streak is at risk.
+
+```yaml
+alias: TaskMate — Streak risk reminder
+trigger:
+ - platform: time
+ at: "20:00:00"
+condition:
+ - condition: template
+ value_template: >
+ {% set children = state_attr('sensor.taskmate_overview', 'children') %}
+ {% set child = children | selectattr('name', 'eq', 'Malia') | first %}
+ {% set today_completions = state_attr('sensor.taskmate_overview', 'todays_completions') | selectattr('child_id', 'eq', child.id) | list %}
+ {{ today_completions | length == 0 and child.current_streak > 0 }}
+action:
+ - service: notify.mobile_app_malias_tablet
+ data:
+ title: "🔥 Your streak is at risk!"
+ message: >
+ {% set children = state_attr('sensor.taskmate_overview', 'children') %}
+ {% set child = children | selectattr('name', 'eq', 'Malia') | first %}
+ You have a {{ child.current_streak }} day streak! Complete a chore before midnight to keep it going.
+```
+
+---
+
+## Display Pending Approvals on a Dashboard Badge
+
+Show a badge on your parent dashboard that turns red when approvals are pending.
+
+```yaml
+# In your dashboard YAML
+- type: entity
+ entity: sensor.taskmate_pending_approvals
+ name: Pending
+ icon: mdi:clipboard-clock
+ state_color: true
+```
+
+Or use a conditional card to show a banner:
+
+```yaml
+- type: conditional
+ conditions:
+ - entity: binary_sensor.taskmate_has_pending_approvals
+ state: "on"
+ card:
+ type: markdown
+ content: >
+ ## ⚠️ {{ states('sensor.taskmate_pending_approvals') }} item(s) need your attention
+ card_mod:
+ style: |
+ ha-card {
+ background: var(--warning-color);
+ color: white;
+ }
+```
+
+---
+
+## Auto-Approve Chores After a Timeout
+
+> **Since v7.0.0 this is built in.** Set **Settings → Auto-approve after (hours)** instead; it approves at the points the child was promised, leaves open-ended chores and bounties for you, and fires `taskmate_chore_auto_approved`. See [Auto-Approve](Auto-Approve.md). The automation below still works if you want different rules.
+
+Automatically approve all pending completions if the parent hasn't approved after 24 hours.
+
+```yaml
+alias: TaskMate — Auto approve after 24h
+trigger:
+ - platform: time_pattern
+ hours: "/1"
+condition:
+ - condition: template
+ value_template: >
+ {{ state_attr('sensor.taskmate_pending_approvals', 'chore_completions') | length > 0 }}
+action:
+ - repeat:
+ for_each: >
+ {{ state_attr('sensor.taskmate_pending_approvals', 'chore_completions') |
+ selectattr('completed_at', 'lt', (now() - timedelta(hours=24)).isoformat()) |
+ list }}
+ sequence:
+ - service: taskmate.approve_chore
+ data:
+ completion_id: "{{ repeat.item.completion_id }}"
+```
+
+---
+
+## Jinja2 Template Examples
+
+Useful templates for dashboard cards and automations.
+
+**Get a specific child's points:**
+```jinja2
+{% set children = state_attr('sensor.taskmate_overview', 'children') %}
+{% set child = children | selectattr('name', 'eq', 'Malia') | first %}
+{{ child.name }} has {{ child.points }} {{ state_attr('sensor.taskmate_overview', 'points_name') }}
+```
+
+**List all children and their streaks:**
+```jinja2
+{% set children = state_attr('sensor.taskmate_overview', 'children') %}
+{% for child in children %}
+ {{ child.name }}: {{ child.current_streak }} day streak
+{% endfor %}
+```
+
+**Check if any child has a pending claim:**
+```jinja2
+{{ state_attr('binary_sensor.taskmate_has_pending_approvals', 'pending_reward_claims') > 0 }}
+```
+
+**Get today's completions for a specific child:**
+```jinja2
+{% set completions = state_attr('sensor.taskmate_overview', 'todays_completions') %}
+{% set child_completions = completions | selectattr('child_id', 'eq', 'a8c8376a') | list %}
+{{ child_completions | length }} chores done today
+```
+
+See also [Watch Complications](Watch-Complications.md) — templates for Apple Watch and Wear OS built on the per-child watch sensor.
diff --git a/wiki/Avatars.md b/wiki/Avatars.md
new file mode 100644
index 00000000..997bd007
--- /dev/null
+++ b/wiki/Avatars.md
@@ -0,0 +1,115 @@
+# Avatars
+
+Avatars are unlockable character icons children earn by hitting milestones. Each avatar is gated behind a requirement — a level, a lifetime-points total, or a best-streak length — giving kids something extra to work toward. Once unlocked, a child can switch to it themselves.
+
+
+
+This page covers the **unlockables system**. For setting a child's starting avatar and general child setup, see [Children](Children.md).
+
+---
+
+## How Unlocking Works
+
+Parents define a **catalogue** of avatars. Each entry has an unlock requirement, and a child unlocks it automatically once they meet that requirement. Unlock state is derived live from the child's stats — there's nothing to award manually.
+
+| Unlock type | Unlocks when… | Measured against |
+|-------------|----------------|------------------|
+| `free` | Always available | — |
+| `level` | The child reaches the given [level](Levels-and-XP.md) | Current level |
+| `points` | The child's lifetime earned points reach the value | `total_points_earned` |
+| `streak` | The child's best streak reaches the value (days) | `best_streak` |
+
+---
+
+## The Default Catalogue
+
+TaskMate ships with a starter catalogue so the feature is useful out of the box. Parents can replace the whole list.
+
+| Avatar | Icon | Unlocks |
+|--------|------|---------|
+| Starter | `mdi:account-circle` | Always available (free) |
+| Rocket | `mdi:rocket-launch` | Level 3 |
+| Robot | `mdi:robot-happy` | Level 5 |
+| Ninja | `mdi:ninja` | Level 10 |
+| Royalty | `mdi:crown` | 500 points earned |
+| Champion | `mdi:trophy` | 1000 points earned |
+| On Fire | `mdi:fire` | 7-day streak |
+| Diamond | `mdi:diamond-stone` | 30-day streak |
+
+---
+
+## Managing the Catalogue
+
+Open the avatar catalogue from the **Admin Panel** (the "Manage avatars" action). Each row needs an MDI icon and an unlock requirement (type plus value). You can add and delete rows and then save to replace the whole catalogue.
+
+Each catalogue entry stores:
+
+| Field | Description |
+|-------|-------------|
+| `id` | Stable identifier (defaults to the icon if omitted) |
+| `label` | Display name, e.g. "Rocket" |
+| `icon` | MDI icon (required) |
+| `unlock_type` | `free`, `level`, `points`, or `streak` |
+| `unlock_value` | The threshold (ignored for `free`) |
+
+Rows without an icon are dropped on save.
+
+---
+
+## Choosing an Avatar
+
+### Children (self-service)
+
+On the [child card](Dashboard-Cards.md), tapping the avatar opens a picker showing the catalogue. Unlocked avatars are selectable; locked ones are dimmed and show their requirement. The picker is available when:
+
+- The card's `allow_avatar_change` option is not set to `false` (it's on by default), and
+- The child has more than one unlocked avatar to choose from
+
+A child can only switch to an avatar they've **unlocked**.
+
+### `choose_avatar` service
+
+The picker calls this service under the hood; you can also call it directly:
+
+```yaml
+service: taskmate.choose_avatar
+data:
+ child_id: a8c8376a
+ icon: mdi:rocket-launch
+```
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `child_id` | Yes | The child switching avatar |
+| `icon` | Yes | The MDI icon of an **unlocked** catalogue avatar |
+
+The service enforces the unlock check — choosing a locked avatar fails. Parents can set any catalogue avatar (including locked ones) via the child's settings in the Admin Panel, which bypasses the unlock requirement.
+
+---
+
+## Sensor Attributes
+
+Each child's entry in the `sensor.taskmate_overview` `children` attribute carries:
+
+- `avatar` — the child's currently selected avatar icon
+- `avatar_options` — the catalogue annotated with per-child unlock state
+
+Each `avatar_options` item contains:
+
+| Field | Description |
+|-------|-------------|
+| `id` | The avatar's ID |
+| `label` | Display name |
+| `icon` | MDI icon |
+| `unlocked` | `true` if this child has met the requirement |
+| `requirement` | Human-readable requirement, e.g. `Level 3`, `500 earned`, `7-day streak` (empty for free) |
+
+---
+
+## Related
+
+- [Children](Children.md) — child setup and the starting avatar
+- [Levels and XP](Levels-and-XP.md) — the level thresholds that gate avatars
+- [Bonus Points](Bonus-Points.md) — streaks and earned-point totals that unlock avatars
+- [Dashboard Cards](Dashboard-Cards.md) — the child card avatar picker
+- [Services](Services.md) — the `choose_avatar` service
diff --git a/wiki/Backup-and-Restore.md b/wiki/Backup-and-Restore.md
new file mode 100644
index 00000000..5becb5a8
--- /dev/null
+++ b/wiki/Backup-and-Restore.md
@@ -0,0 +1,78 @@
+# Backup and Restore
+
+TaskMate can export your entire setup to a single file and restore it later. Use it to keep a safety copy before big changes, to move TaskMate to another Home Assistant instance, or to recover after a mistake.
+
+
+
+Added in v4.0.0.
+
+---
+
+## Where to Find It
+
+Open the **Admin Panel → Settings** tab and scroll to the **Backup & restore** section. It has two buttons:
+
+- **Export backup** — download a backup file.
+- **Restore backup** — upload a backup file and restore it.
+
+See [Admin Panel](Admin-Panel.md) for how to open the panel.
+
+---
+
+## Exporting a Backup
+
+Click **Export backup**. TaskMate downloads a JSON file named `taskmate-backup.json` containing a full snapshot of your setup.
+
+### What's included
+
+The export is a complete copy of TaskMate's stored data, including:
+
+- Children
+- Chores
+- Rewards
+- Penalties and bonuses
+- Task groups
+- Completions and reward claims
+- Points transactions and pool allocations
+- Badges and awarded badges
+- Parent notification recipients and notification config
+- Timed sessions
+- The [admin audit log](Admin-Audit-Log.md)
+- All settings
+
+The file is wrapped with an export version marker (`taskmate_export_version`) and a `data` object. Treat it as private — it contains your family's full TaskMate history.
+
+---
+
+## Restoring a Backup
+
+1. Click **Restore backup**.
+2. Choose a previously exported `taskmate-backup.json` file.
+3. Confirm the prompt.
+4. **Reload the integration** afterwards so per-child entities refresh.
+
+### Important cautions
+
+> **Restore replaces everything.** A restore is a *full replace*, not a merge. All current TaskMate data is overwritten with the contents of the backup. This **cannot be undone** — export a fresh backup of your current setup first if you might want it back.
+
+- Only valid TaskMate backup files are accepted; an unrecognised file is rejected with an error and nothing changes.
+- After a restore, per-child entities (sensors, buttons) only refresh fully once the integration is reloaded (Settings → Devices & Services → TaskMate → Reload, or restart Home Assistant).
+- Restoring a backup taken on a different Home Assistant instance brings that instance's data wholesale; notify-service names referenced by recipients may need updating to match the new host.
+- **Who may do what stays with your instance, not the file.** A restore keeps your current parent list, each child's linked Home Assistant account, the "Require a linked account per child" setting, the unlock allowlist, kiosk PINs and the audit log. A child who isn't already on your instance comes back with no linked account; link them again in **Children**. This means a backup somebody else prepared can't make their account a parent or hand them a device.
+- **A backup file carries no secrets.** Kiosk PIN hashes, the calendar feed link's token and any unlock still running are left out. After a restore, set any PINs again and, if you use the [calendar feed](Calendar.md#the-token-and-regenerating-it), click **Regenerate link** and re-subscribe.
+- A record the file holds that TaskMate can't load (say, a word where a number belongs) is skipped and noted in the log; everything else is restored.
+
+---
+
+## Tips
+
+- Export a backup before bulk edits, before upgrading across a major version, or before experimenting with new features.
+- Backups are plain JSON — keep them somewhere safe and versioned (the filename is always `taskmate-backup.json`, so rename copies you want to keep).
+
+---
+
+## Related
+
+- [Admin Panel](Admin-Panel.md) — where Backup & restore lives
+- [Admin Audit Log](Admin-Audit-Log.md) — included in the export
+- [Troubleshooting](Troubleshooting.md) — if entities don't refresh after a restore
diff --git a/wiki/Birthday-Mode.md b/wiki/Birthday-Mode.md
new file mode 100644
index 00000000..63444206
--- /dev/null
+++ b/wiki/Birthday-Mode.md
@@ -0,0 +1,105 @@
+# Birthday Mode
+
+Give each child a birthday and TaskMate makes the day feel special: every chore pays extra, there's a birthday banner with confetti on their card, they earn a **Birthday** badge, and if you like, they get the day off chores altogether.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## Setting a Birthday
+
+**TaskMate panel → Children → Edit → Birthday**
+
+| Format | Example | Result |
+|--------|---------|--------|
+| `YYYY-MM-DD` | `2018-09-28` | Birthday on 28 September, and the banner shows their age ("8 today!") |
+| `MM-DD` | `09-28` | Birthday on 28 September, with no age shown |
+
+Leave it empty and birthday mode is simply off for that child. Impossible dates and dates in the future are refused.
+
+The [setup wizard](Getting-Started.md) can also take a birthday when you add children.
+
+### 29 February
+
+A leap-day birthday is celebrated on **28 February** in years that don't have a 29th.
+
+---
+
+## What Happens on the Day
+
+| | What the child gets |
+|---|---|
+| **Bonus points** | Every chore pays the birthday multiplier (**2×** by default). |
+| **Banner** | A "Happy birthday, Mia — 8 today!" banner on the child card and the points display card, showing the multiplier. |
+| **Confetti** | The child card plays confetti the first time it's opened that day. |
+| **Badge** | The built-in **Birthday** badge is awarded. |
+| **Day off** *(optional)* | Non-mandatory chores are hidden for the day. |
+| **Notification** *(optional)* | A "Happy birthday!" message in the morning. |
+
+---
+
+## Settings
+
+**TaskMate panel → Settings → History & streaks**
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Birthday points multiplier** | `2` | Chore points on a child's birthday, from `1` to `5`. `1` turns the bonus off. |
+| **Birthday day off** | Off | Hide non-mandatory chores on a child's birthday. |
+
+These apply to every child. The birthday itself is set per child.
+
+---
+
+## Bonus Points
+
+The multiplier is applied on top of whatever the chore would normally pay that day. [Difficulty tiers](Difficulty-Tiers.md), [Chore Roulette](Chore-Roulette.md) and the weekend bonus all still apply, and the birthday multiplier rides on top of them.
+
+The bonus follows the day the chore was **done**, not the day it was approved. A chore done on the birthday and approved the next morning still pays double.
+
+If a birthday completion is undone or rejected, the full amount, including the birthday bonus, is taken back.
+
+---
+
+## The Day Off
+
+With **Birthday day off** switched on:
+
+- **Non-mandatory chores** are hidden for that child for the day.
+- **[Mandatory chores](Mandatory-Chores.md)** stay. Medicine and teeth still matter on a birthday.
+- The day **never breaks their streak**, and it isn't counted as a required day for a perfect week.
+- Streak-at-risk and bedtime reminders aren't sent for the hidden chores.
+- It never uses up a [streak freeze](Streak-Freezes.md).
+
+---
+
+## The Birthday Badge
+
+**Birthday** is a built-in bronze badge. Like every built-in badge, a child earns it once. You can also use the *Birthday today* metric when you create your own badges. See [Achievement Badges](Achievement-Badges.md).
+
+---
+
+## Birthday Notification
+
+Turn on the **Birthday** notification type under **TaskMate panel → Notifications** to send the child a message on the morning of their birthday:
+
+> Happy birthday, Mia! Every chore pays 2× today.
+
+It goes out at the child's notification time, or **08:00** if they don't have one. It's off by default. See [Notifications](Notifications.md).
+
+---
+
+## For Automations
+
+On the day, TaskMate fires a `taskmate_celebration` event with `kind: birthday`, plus the `multiplier` and, when the birth year is known, the child's `age`. Use it to play a song on the speakers or change the lights.
+
+---
+
+## Related
+
+- [Children](Children.md) — adding and editing children
+- [Celebrations](Celebrations.md) — the confetti and celebration events
+- [Achievement Badges](Achievement-Badges.md) — the Birthday badge
+- [Streak Freezes](Streak-Freezes.md) — other ways a streak is protected
diff --git a/wiki/Bonus-Points.md b/wiki/Bonus-Points.md
new file mode 100644
index 00000000..c652f081
--- /dev/null
+++ b/wiki/Bonus-Points.md
@@ -0,0 +1,143 @@
+# Bonus Points
+
+TaskMate has three bonus point systems on top of regular chore completion. All are configured in the **TaskMate** panel → **Settings**.
+
+
+
+> **See also:** From v4.0.0 TaskMate also runs a set of **automatic point mechanics** — a random daily **surprise bonus**, periodic **savings interest**, and optional **points decay**. These award (or remove) points independently of chores and are documented on the [Points Economy](Points-Economy.md) page. The surprise bonus is the automatic cousin of the manual bonuses described here.
+
+---
+
+## Weekend Points Multiplier
+
+Children earn extra points for completing chores on Saturdays and Sundays.
+
+| Setting | Default | Range |
+|---------|---------|-------|
+| Weekend Points Multiplier | `2.0` | `1.0` – `5.0` |
+
+**How it works:**
+- The multiplier applies to the base points of the chore
+- A 10-point chore on Saturday with a 2.0× multiplier earns 10 + 10 = **20 points**
+- The base points and bonus points are logged as **separate transactions** in the activity feed
+- The multiplier is based on the **completion date**, not the approval date — fair for weekend chores approved on Monday
+
+**Set to `1.0` to disable.**
+
+---
+
+## Streak Milestone Bonuses
+
+Children earn bonus points when they hit streak milestones.
+
+| Setting | Default |
+|---------|---------|
+| Streak Milestone Bonuses | `on` |
+| Streak Milestone Configuration | `3:5, 7:10, 14:20, 30:50, 60:100, 100:200` |
+
+### Default Milestones
+
+| Streak | Bonus |
+|--------|-------|
+| 3 days | +5 points |
+| 7 days | +10 points |
+| 14 days | +20 points |
+| 30 days | +50 points |
+| 60 days | +100 points |
+| 100 days | +200 points |
+
+### Custom Milestones
+
+Enter your own milestones as `days:points` pairs, comma-separated:
+
+```
+3:5, 7:10, 14:20, 30:50, 60:100, 100:200
+```
+
+**Rules:**
+- Day counts must be positive integers
+- Points must be positive integers
+- Pairs must be separated by commas
+- Invalid format shows a validation error on save and falls back to the default list
+- Leave the field empty to disable all milestones without turning off the toggle
+
+**Examples:**
+
+More frequent, smaller bonuses for younger kids:
+```
+1:2, 3:5, 5:8, 7:15, 14:30, 30:75
+```
+
+Fewer, bigger milestones:
+```
+7:15, 30:75, 100:250
+```
+
+### Milestone Behaviour
+
+- Milestones are **re-earnable** — if a streak resets to 0, children can earn the same milestones again
+- The `streak_milestones_achieved` list is cleared when a streak resets, so children start fresh
+- Each milestone is only awarded once per streak cycle — a child won't earn the 7-day bonus twice in the same streak
+- The bonus is logged in the activity feed as a streak milestone event
+
+---
+
+## Perfect Week Bonus
+
+Children earn a bonus when they complete at least one chore every day Monday–Sunday.
+
+| Setting | Default | Range |
+|---------|---------|-------|
+| Perfect Week Bonus | `on` | — |
+| Perfect Week Bonus Points | `50` | `0` – `1000` |
+| Perfect week needs all tasks (`perfect_week_requires_all_chores`) | `off` | on / off |
+
+**How it works:**
+- Checked automatically every **Monday at midnight**
+- Requires at least one **approved** chore completion on each of the 7 days (Mon–Sun) — or, with **Perfect week needs all tasks** enabled, *every* chore due that day must be done before the day counts
+- Each week is awarded once per child — duplicates are prevented even if the check runs twice
+- The awarded weeks are stored as a list of Monday ISO dates on the child record
+- The bonus is logged in the activity feed
+
+---
+
+## Streak Tracking
+
+### How Streaks Work
+
+- A streak increments when a child completes at least one chore on a given day
+- With **Streak needs all tasks** (`streak_requires_all_chores`) enabled, the day only counts once *every* chore due that day is done
+- Streaks are checked every night at **midnight** by the coordinator scheduler
+- The check compares `last_completion_date` against today's date
+
+### Streak Reset Mode
+
+| Mode | Behaviour |
+|------|-----------|
+| `reset` (default) | Missing a day resets the streak to 0 |
+| `pause` | Missing a day pauses the streak — it resumes from where it left off on the next completion |
+
+**Pause mode** is useful for holidays, sick days, or families that want to be less strict. The `streak_paused` flag is set on the child record when a day is missed in pause mode.
+
+### Best Streak
+
+`best_streak` is the highest `current_streak` value the child has ever had. It never decreases and is used in the Leaderboard card's streak ranking.
+
+---
+
+## Settings Reference
+
+All bonus settings in one place:
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| Weekend Points Multiplier | `2.0` | Multiplier on Sat/Sun — set `1.0` to disable |
+| Streak Milestone Bonuses | `on` | Master toggle for all milestone bonuses |
+| Streak Milestone Configuration | `3:5, 7:10, 14:20, 30:50, 60:100, 100:200` | Custom `days:points` pairs |
+| Streak needs all tasks | `off` | Only extend a streak once every chore due that day is done |
+| Perfect Week Bonus | `on` | Toggle perfect week bonus |
+| Perfect Week Bonus Points | `50` | Points awarded per perfect week |
+| Perfect week needs all tasks | `off` | A day counts only when every chore due that day is done |
+| Streak Reset Mode | `reset` | `reset` or `pause` |
+| History Days to Keep | `90` | Completion history retention: 30–365 days |
+| Notification Service | *(empty)* | HA notify service for approval alerts e.g. `notify.mobile_app_your_phone` |
diff --git a/wiki/Bonus-Subtasks.md b/wiki/Bonus-Subtasks.md
new file mode 100644
index 00000000..52eaf256
--- /dev/null
+++ b/wiki/Bonus-Subtasks.md
@@ -0,0 +1,114 @@
+# Bonus Subtasks
+
+Bonus Subtasks are optional extra-credit tasks embedded within a parent chore. They let children earn additional points by going above and beyond the base chore.
+
+
+
+---
+
+## How It Works
+
+```
+Child completes parent chore → Bonus subtasks unlock → Child completes subtask → Extra points awarded
+```
+
+A "Clean Bedroom" chore worth 10 points might have bonus subtasks like "Organise bookshelf (+5)" and "Vacuum under bed (+5)". The child earns the base 10 for cleaning, plus up to 10 more if they tackle the extras.
+
+---
+
+## Configuring Bonus Subtasks
+
+Bonus subtasks are configured as part of a chore's settings. Each subtask has:
+
+| Field | Required | Default | Description |
+|-------|----------|---------|-------------|
+| **Name** | Yes | — | Subtask display name |
+| **Points** | No | `5` | Points awarded on completion |
+| **Description** | No | `""` | Optional details |
+
+Subtasks are stored as a list on the chore object (`bonus_subtasks`). Each subtask gets an auto-generated unique ID.
+
+### Adding Subtasks
+
+1. Edit a chore via the config flow or admin panel
+2. In the bonus subtasks section, add one or more subtasks
+3. Save the chore
+
+---
+
+## Completion Flow
+
+1. **Parent chore must be completed first** — bonus subtasks are locked until the parent chore is ticked off by the same child on the same day
+2. **Child completes a subtask** — the subtask appears as completable on the child card after the parent chore is done
+3. **Approval follows the parent chore's setting** — if the parent requires approval, the subtask completion is also pending until approved
+4. **Points are separate** — subtask points are awarded independently from the parent chore's points
+5. **Tap again to undo** *(v4.4.4+)* — tapping a completed bonus subtask a second time un-completes it, reversing just that subtask's points and leaving the parent chore done. This mirrors the tap-to-undo behaviour of top-level chores and works on the classic and all designed card styles. As with a chore undo, it removes already-awarded points and so is admin/parent-only.
+
+### Approval Display
+
+When a bonus subtask is pending approval, it appears in the approvals card with the format:
+
+> **Clean Bedroom › Organise Bookshelf** — +5 Stars
+
+### Streak Behaviour
+
+Bonus subtask completions do **not** count toward streak tracking. Only the parent chore completion affects streaks.
+
+---
+
+## Service
+
+### `taskmate.complete_bonus_subtask`
+
+Complete a bonus subtask for a child.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `chore_id` | Yes | ID of the parent chore |
+| `bonus_subtask_id` | Yes | ID of the subtask |
+| `child_id` | Yes | ID of the child |
+
+```yaml
+service: taskmate.complete_bonus_subtask
+data:
+ chore_id: b3f9a12c
+ bonus_subtask_id: sub_abc123
+ child_id: a8c8376a
+```
+
+**Errors:**
+- Parent chore not completed today by this child
+- Subtask already completed today by this child
+- Invalid chore, subtask, or child ID
+
+---
+
+## Sensor Attributes
+
+Bonus subtask completions appear in `todays_completions` with:
+
+| Field | Value |
+|-------|-------|
+| `chore_name` | `"Parent Chore › Subtask Name"` |
+| `points` | Subtask points (not parent points) |
+| `bonus_subtask_id` | The subtask ID |
+| `timed_duration_seconds` | `0` |
+
+The chore's `bonus_subtasks` array in the sensor attributes lists each subtask with `id`, `name`, `points`, and `description`.
+
+---
+
+## Tips
+
+- **Keep subtasks genuinely optional** — they should reward extra effort, not become expected
+- **Use lower point values** than the parent chore — subtasks are bonuses, not the main reward
+- **Good for teaching thoroughness** — "Make Bed" base + "Arrange pillows neatly" bonus + "Tidy nightstand" bonus
+- **Works with any chore type** — specific days, recurring, one-shot, and timed chores can all have bonus subtasks
+
+---
+
+## Related
+
+- [Chores](Chores.md) — parent chore configuration
+- [Services](Services.md) — full service reference
+- [Dashboard Cards](Dashboard-Cards.md) — how subtasks appear on the child card
diff --git a/wiki/Bonuses.md b/wiki/Bonuses.md
new file mode 100644
index 00000000..4101476d
--- /dev/null
+++ b/wiki/Bonuses.md
@@ -0,0 +1,190 @@
+# Bonuses
+
+Bonuses are a point-awarding system that complements the Penalties system. While Penalties deduct points for negative behaviors, Bonuses award points for positive achievements and special occasions.
+
+
+
+
+## Overview
+
+The Bonuses feature allows you to:
+- **Create custom bonuses** that award points to children
+- **Manage bonuses** through the Bonuses card in your dashboard
+- **Apply bonuses** instantly via the UI or services
+- **Assign bonuses** to specific children or all children
+- **Categorize bonuses** with icons and descriptions
+
+## How Bonuses Work
+
+1. **Create a Bonus** - Define a bonus with a name, point value, optional description, and icon
+2. **Assign It** - Choose which children the bonus applies to (or leave empty for all)
+3. **Apply the Bonus** - Award the points to a child through the Bonuses card or via service call
+4. **Points Awarded** - The child receives the bonus points immediately in their account
+
+### Bonuses vs Penalties
+
+| Aspect | Bonuses | Penalties |
+|--------|---------|-----------|
+| **Purpose** | Reward positive behaviors | Discourage negative behaviors |
+| **Point Effect** | Awards points (+) | Deducts points (-) |
+| **Common Use Cases** | Perfect week, good report card, extra chores | Rule breaking, incomplete chores, screen time violations |
+| **Trigger** | Parent recognition, special events | Behavioral issues, incomplete tasks |
+
+## The Bonuses Card
+
+The Bonuses Card provides a green-themed interface for managing all your bonuses. Key features:
+
+- **List of Bonuses** - View all defined bonuses with their point values
+- **Add New Bonus** - Create a new bonus definition directly from the card
+- **Apply Bonus** - Select a child and click the bonus to award points
+- **Edit/Delete** - Manage existing bonuses
+- **Visual Indicators** - Color-coded icons help distinguish different bonus types
+
+### Who sees what
+
+Since v5.0.4 the card matches the backend permissions:
+
+| Role | Apply a bonus | Add / edit / delete bonuses |
+|------|---------------|------------------------------|
+| Home Assistant admin | Yes | Yes |
+| [TaskMate parent](Parent-Access.md) | Yes | No — the manage pencil is hidden |
+| Child / anyone else | No | No — the list is read-only |
+
+Before v5.0.4 the card showed every control to everyone, and a parent tapping **Apply** got `Unauthorized`.
+
+### Lovelace Configuration
+
+Add the Bonuses Card to your dashboard:
+
+```yaml
+type: custom:taskmate-bonuses-card
+entity: sensor.taskmate_overview
+title: Bonuses
+```
+
+## Creating and Managing Bonuses
+
+### Create a Bonus
+
+1. Open the Bonuses Card on your dashboard
+2. Click "Add Bonus" or the **+** button
+3. Fill in the bonus details:
+ - **Name** - The bonus title (e.g., "Perfect Week")
+ - **Points** - Points awarded when applied (1-10000)
+ - **Description** (optional) - Details about when to use this bonus
+ - **Icon** (optional) - MDI icon for visual identification
+ - **Assigned To** (optional) - Specific children (leave empty for all)
+4. Click Save
+
+### Update a Bonus
+
+1. In the Bonuses Card, click the **edit** icon on the bonus
+2. Modify the desired fields
+3. Click Save
+
+### Remove a Bonus
+
+1. In the Bonuses Card, click the **delete** icon on the bonus
+2. Confirm the deletion
+
+### Apply a Bonus
+
+1. In the Bonuses Card, select a child from the dropdown
+2. Click the bonus you want to apply
+3. The points are instantly awarded to that child
+
+## Services
+
+The Bonuses system provides four services for advanced automation:
+
+### taskmate.add_bonus
+Create a new bonus definition.
+
+### taskmate.update_bonus
+Update an existing bonus definition.
+
+### taskmate.remove_bonus
+Remove a bonus definition.
+
+### taskmate.apply_bonus
+Award bonus points to a child (calls the internal `add_points` service).
+
+See the [Services](Services.md) page for detailed parameter documentation and YAML examples.
+
+### Undoing an applied bonus (v4.0.0)
+
+Applied the wrong bonus, or gave it to the wrong child? An admin can reverse it. Each applied-bonus row in the activity log shows an **Undo** button, which restores the child's balance and earned total and removes the transaction. The same action is available as the `taskmate.undo_transaction` service. See [Points Economy](Points-Economy.md#per-action-undo) and [Services](Services.md).
+
+## Common Use Cases
+
+### Perfect Week Bonus
+Award extra points when a child completes all assigned chores in a week.
+
+**Bonus Details:**
+- Name: "Perfect Week"
+- Points: 25
+- Description: "Completed all chores for the week"
+- Icon: `mdi:star`
+
+### Report Card Bonus
+Reward good grades or school achievements.
+
+**Bonus Details:**
+- Name: "Great Grades"
+- Points: 50
+- Description: "Honor roll or excellent report card"
+- Icon: `mdi:school`
+
+### Special Event Bonus
+Celebrate birthdays, holidays, or milestones.
+
+**Bonus Details:**
+- Name: "Birthday Bonus"
+- Points: 100
+- Description: "Happy Birthday!"
+- Icon: `mdi:birthday-cake`
+
+### Chore Motivation Bonus
+Quick bonuses for exceeding expectations.
+
+**Bonus Details:**
+- Name: "Extra Effort"
+- Points: 10
+- Description: "Completed a chore ahead of schedule"
+- Icon: `mdi:lightning-bolt`
+
+## Tips & Best Practices
+
+**Start Simple** - Begin with a few bonuses (Perfect Week, Good Grades, Birthday) and expand based on your family's needs.
+
+**Balance Your Economy** - Keep bonus point values reasonable compared to chore rewards to maintain motivation balance. Example: If chores award 5-20 points, bonuses might award 10-50 points.
+
+**Use Icons Consistently** - Choose recognizable MDI icons that make bonuses instantly identifiable on the card.
+
+**Assign Strategically** - Use assignment to create age-appropriate bonuses. Younger children might have simpler bonus criteria.
+
+**Celebrate Often** - Bonuses are more effective when applied promptly and for genuine achievements. Don't overuse them.
+
+**Combine with Automations** - Use the `apply_bonus` service in automations to award bonuses based on Home Assistant sensor values (e.g., door lock, presence, weather).
+
+## Troubleshooting
+
+**Bonus Not Appearing on Card**
+- Verify the bonus was saved (check the card's bonus list)
+- Refresh your dashboard (F5 or hard refresh)
+- Check that the `sensor.taskmate_overview` entity is available
+
+**Can't Apply Bonus**
+- Ensure a child is selected from the dropdown
+- Verify the bonus is assigned to that child (or assigned to all if "Assigned To" is empty)
+- Check Home Assistant logs for errors
+
+**Points Not Awarded**
+- Confirm the child's point balance increased after applying the bonus
+- Verify the `apply_bonus` service is properly configured (if using automations)
+- Check that the bonus points value is correctly set
+
+**Service Call Fails**
+- Verify the `bonus_id` and `child_id` are correct (use Developer Tools to find IDs)
+- Ensure the bonus and child still exist
+- Check Home Assistant logs for detailed error messages
diff --git a/wiki/Bounty-Board.md b/wiki/Bounty-Board.md
new file mode 100644
index 00000000..15e10676
--- /dev/null
+++ b/wiki/Bounty-Board.md
@@ -0,0 +1,134 @@
+# Bounty Board
+
+Some jobs aren't chores. Nobody washes the car every Tuesday, but when it needs doing you'd happily pay for it. Post it as a **bounty**: a one-off job with a fixed number of points that any eligible child can claim. The first to claim it gets it, finishes it, and it goes through your normal approval queue.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## How It Works
+
+1. **You post a bounty** — "Wash the car — 50 points" — from the **Bounties** page in the TaskMate panel.
+2. **A child claims it.** It is now locked to them for the claim time (2 hours by default). Their siblings see "Vaiha is on it" with the time left.
+3. **They finish and tap Done.** The job lands in your approval queue like any chore completion, with a photo if you asked for one.
+4. **You approve**, and the points are paid.
+
+If the claim runs out before the child taps Done, the bounty goes back on the board for anyone to claim. A bounty nobody claims closes when it expires.
+
+---
+
+## Posting a Bounty
+
+**TaskMate panel → Bounties → + Post a bounty** (or **New → Bounty**, or **New bounty** under Quick actions on the Today page)
+
+
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Title** | — | What the job is, e.g. "Clear out the garage" |
+| **Description** | — | Optional detail: what "done" looks like |
+| **Points** | — | What it pays. Quick picks are offered |
+| **Icon** | — | Any MDI icon |
+| **Claim lock** | 2 hours | How long a child has to finish once they claim it (1–48 hours). Never runs past the expiry |
+| **Expires** | never | Quick picks or a date. An unclaimed bounty closes at this time |
+| **Who can claim** | everyone | Limit it to particular children |
+| **Photo proof** | off | The child must attach a photo when they finish |
+| **Notify eligible children** | off | Sends the *Bounty posted* notification |
+
+The page has three tabs: **Active**, **Waiting approval** and **History**. From Active you can edit a bounty, remove it, or **Release claim** to hand a claimed bounty back to the board.
+
+---
+
+## The Rules
+
+- **One claim at a time.** A child can only hold one bounty at once, so nobody hoards the good ones.
+- **Rejecting gives it back to the same child** with a fresh claim lock, even if the bounty has since expired. They have work to redo, so it stays theirs.
+- **Claims that run out return to the board.** There's no cool-down; the same child can claim it again.
+- **Editing.** While a bounty is open you can change anything. Once it's claimed, only the points and expiry can change. Raising the points while it waits for approval changes what the approval pays.
+- **Removing.** A bounty can't be removed while a finished job is waiting for your approval. Approve or reject it first.
+- **Children who can't claim don't see it.** A bounty limited to one child doesn't appear on the other children's cards.
+- **It counts like a chore.** An approved bounty counts toward streaks, badges, challenges and [recaps](Recaps.md).
+
+---
+
+## The Card
+
+Each child gets their own view of the board. The card shows:
+
+- **Open** bounties they can claim, with points, expiry, who else can claim it and a **Claim** button
+- **Their claimed bounty**, with a countdown bar and **Done** / **Give back** buttons
+- Bounties **a sibling is on**, greyed out with the time left on the claim
+- Jobs **waiting for approval**, with an undo while the [child undo window](Child-Undo-Window.md) allows
+- **Recently completed** bounties from the last 24 hours
+
+Children can also claim and finish bounties on the shared wall tablet: switch on **Bounty Board** in the [kiosk card](Kiosk-Mode.md#bounties) *(v6.3.0)*.
+
+### Adding the card
+
+```yaml
+type: custom:taskmate-bounty-card
+entity: sensor.taskmate_overview
+child_id: b803da068e6a4b21
+```
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `entity` | string | **required** | The TaskMate overview sensor |
+| `child_id` | string | **required** | Whose board this is. Find IDs in the panel with **Show IDs** switched on |
+| `title` | string | `Bounty Board` | Card header title |
+| `card_design` | string | global default | `classic`, `playroom`, `console`, `cleanpro`, `accessible` or `graphite` |
+| `header_color` | string | `#e67e22` | Header banner colour |
+
+---
+
+## Notifications
+
+Both are off until you switch them on under **Notifications**:
+
+| Type | Sent to | When |
+|------|---------|------|
+| **Bounty posted** | Eligible children | You post a bounty with *Notify eligible children* on |
+| **Claim about to lapse** | The child holding the claim | 15 minutes before their claim runs out |
+
+---
+
+## Services
+
+| Service | Who | Description |
+|---------|-----|-------------|
+| `taskmate.post_bounty` | Parent | Post a bounty. `title` and `points` are required; `description`, `icon`, `expires_at`, `eligible_child_ids`, `claim_hours`, `require_photo` and `notify_children` are optional |
+| `taskmate.update_bounty` | Parent | Change a bounty by `bounty_id`, same fields as above |
+| `taskmate.remove_bounty` | Parent | Remove a bounty |
+| `taskmate.claim_bounty` | Child | Claim a bounty (`bounty_id`, `child_id`) |
+| `taskmate.give_back_bounty` | Child | Hand a claim back to the board |
+| `taskmate.complete_bounty` | Child | Mark it done. `photo_url` is required when the bounty asks for photo proof |
+
+The new `sensor.taskmate_bounties` sensor's state is the number of open bounties.
+
+### Events
+
+Every step fires a `taskmate_bounty_*` event you can automate on: `posted`, `updated`, `removed`, `claimed`, `given_back`, `claim_lapsed`, `completed`, `approved`, `rejected`, `released`, `withdrawn` and `expired`.
+
+---
+
+## Ideas
+
+| Bounty | Points | Claim lock |
+|--------|--------|-----------|
+| Wash the car | 50 | 4 hours |
+| Clear out the garage | 80 | 6 hours |
+| Weed the patio (photo proof) | 30 | 2 hours |
+| Help carry the shopping in | 10 | 1 hour |
+
+---
+
+## Related
+
+- [Chore Auctions](Chore-Auctions.md) — the other way to shift a job nobody wants
+- [Chores](Chores.md) — regular, recurring jobs
+- [Photo Proof](Photo-Proof.md) — how evidence photos work
+- [Kiosk Mode](Kiosk-Mode.md#bounties) — bounties on the shared wall tablet
+- [Managing Rewards](Managing-Rewards.md) — the approval queue
+- [Automations](Automations.md) — every TaskMate bus event
diff --git a/wiki/Calendar.md b/wiki/Calendar.md
new file mode 100644
index 00000000..d57adc01
--- /dev/null
+++ b/wiki/Calendar.md
@@ -0,0 +1,113 @@
+# Calendar
+
+From v4.1.0 TaskMate exposes a native **calendar entity per child** — a read-only Home Assistant calendar that publishes that child's chore occurrences and away periods as events. The events are derived live from TaskMate's own schedule and assignment engine, so there is no second store to keep in sync, and the calendar shows exactly who would see each chore on each day.
+
+---
+
+## Per-Child Calendar Entities
+
+TaskMate creates one calendar entity for every child, named `TaskMate `, with the entity id `calendar.taskmate_` (for example, a child called Malia gets `calendar.taskmate_malia`). New entities appear automatically as children are added.
+
+Each calendar publishes that child's upcoming chores as events:
+
+- **Timed chores** — a chore in a time-of-day period (morning / afternoon / evening / night) becomes a **timed event** inside that period's window. The window comes from the same time-of-day boundaries used everywhere else (see [Settings](Settings.md)).
+- **Anytime chores** — chores with no time category become **all-day events** for the day they fall on.
+- **Away days** — when a child is on vacation or otherwise away, those days are coalesced into multi-day **all-day "Away" events**, and chores are hidden on those days (matching the rest of the integration). See [Vacation Mode](Vacation-Mode.md).
+
+Each chore event's description carries a compact summary — `TaskMate chore · N pts` (plus the time category for timed chores).
+
+The calendar projects the **schedule**, not today's done/not-done state: it shows the chores a child would be assigned, regardless of whether they have already been completed.
+
+---
+
+## How Far Ahead It Projects
+
+How many days of chore events each calendar publishes is controlled by the **Calendar projection** setting — *"Days ahead each chore publishes to calendars"* (`calendar_projection_days`, default `14`, range 1–90). Raise it for more planning visibility, lower it for fewer entries. See [Settings](Settings.md).
+
+---
+
+## Using the Calendar Entities
+
+Because these are standard Home Assistant calendar entities, they work anywhere HA calendars do:
+
+- The built-in **Calendar** dashboard panel
+- Lovelace **calendar cards**
+- **Automations** that trigger on calendar events (for example, a reminder when a morning chore is due)
+
+The entities are **read-only** — completing a chore from the calendar is intentionally not supported. Use the [Approvals Card](Approvals-Card.md) or a child card for that.
+
+---
+
+## The TaskMate Calendar Card
+
+TaskMate also ships a dedicated Lovelace **`taskmate-calendar-card`** — a one-day, per-child view that steps through days with **Prev / Today / Next** navigation and colour-codes each chore by state.
+
+
+
+The card's legend marks each chore as:
+
+| State | Colour |
+|-------|--------|
+| **Approved** | Green |
+| **Pending** | Amber |
+| **Due** | Grey |
+
+```yaml
+type: custom:taskmate-calendar-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+title: Task Calendar
+header_color: "#3498db"
+```
+
+See [Dashboard Cards](Dashboard-Cards.md) for the full card reference.
+
+---
+
+## Calendar Subscription (ICS Feed)
+
+As well as the per-child HA calendar entities above, TaskMate can publish your upcoming chores as a single subscribable **ICS feed** you can add to Google Calendar, Apple Calendar, Outlook, or any app that accepts a calendar URL. Unlike the HA entities — which live inside Home Assistant — this feed is an external link, so a parent (or child) can see upcoming chores in their everyday calendar app without opening HA.
+
+The feed is served read-only at:
+
+```
+/api/taskmate/calendar.ics?token=
+```
+
+It covers the same horizon as the calendar entities, controlled by the **Calendar projection** setting.
+
+### Finding the Subscribe URL
+
+The subscribe link lives in the **Admin Panel → Settings**, in the **Calendar subscription** section.
+
+1. Open the **TaskMate** panel in the HA sidebar and go to **Settings**.
+2. Scroll to **Calendar subscription** and click **Show subscribe link**.
+3. The full URL (including its token) appears in a read-only box. Use **Copy** to put it on the clipboard.
+
+### Subscribing in a Calendar App
+
+Add the copied URL as a **subscribed / internet calendar** in your app:
+
+- **Google Calendar** — *Other calendars → + → From URL → paste the link*
+- **Apple Calendar** — *File → New Calendar Subscription… → paste the link* (iOS: *Settings → Calendar → Accounts → Add Account → Other → Add Subscribed Calendar*)
+- **Outlook** — *Add calendar → Subscribe from web → paste the link*
+
+The feed is **read-only**: chores appear as events, but you can't complete or change anything from the calendar app. Use a child card or the [Approvals Card](Approvals-Card.md) for that.
+
+### The Token, and Regenerating It
+
+The URL is **token-protected** — it's public-by-link (a calendar app can't sign in to Home Assistant), so anyone with the full link can read the feed. Treat it like a private link and share it carefully.
+
+If a link is ever shared too widely, click **Regenerate link** in the same Settings section. This issues a **new token and a new URL, and immediately invalidates the old one** — any app still subscribed to the previous link stops receiving the feed and must be re-subscribed with the new URL.
+
+> **Per-child HA calendars vs. the ICS feed:** the [per-child calendar entities](#per-child-calendar-entities) are separate Home Assistant calendars used *inside* HA (dashboards, automations, the calendar card). The ICS subscription is a single external feed you add to an *outside* calendar app. They're independent — using one doesn't require the other.
+
+---
+
+## Related
+
+- [Dashboard Cards](Dashboard-Cards.md) — the `taskmate-calendar-card` and other cards
+- [Vacation Mode](Vacation-Mode.md) — how "Away" events are produced
+- [Two-Way Calendar](Two-Way-Calendar.md) — add, move and skip chores from Home Assistant's calendar
+- [Chores](Chores.md) — chore scheduling, time categories, and assignment
+- [Settings](Settings.md) — the Calendar projection setting and time-of-day boundaries
diff --git a/wiki/Card-Design-Styles.md b/wiki/Card-Design-Styles.md
new file mode 100644
index 00000000..08e637b5
--- /dev/null
+++ b/wiki/Card-Design-Styles.md
@@ -0,0 +1,99 @@
+# Card Design Styles
+
+Every TaskMate card can be themed independently, with a global default that any card can inherit. Pick a single look for your whole dashboard, or give each card its own style — completion sounds, layout, and behaviour are unchanged; only the visual skin differs.
+
+
+
+> **New in v4.2.0** (#539)
+
+---
+
+## The Six Styles
+
+| Style | Feel | Accent | Fonts |
+|-------|------|--------|-------|
+| **Classic** | The original TaskMate look — the default, unchanged | Per-card `header_color` / HA theme | HA theme fonts |
+| **Playroom** | Warm, rounded, picture-book — soft cream backgrounds | Purple | Baloo 2 / Nunito |
+| **Console** | Dark, neon-accented game-HUD with glow effects | Cyan | Space Grotesk / Inter / JetBrains Mono |
+| **Clean Pro** | Minimal, flat, professional SaaS with low-contrast shadows | Blue | Manrope / Inter |
+| **Accessible** | High contrast, colour-blind safe, dyslexia-friendly type | Okabe-Ito blue | Atkinson Hyperlegible |
+| **Graphite** | Clean and corporate — a quiet, system-looking dashboard | Neutral slate | Inter |
+
+**Classic** is the default and is left exactly as it was — existing dashboards look identical until you opt in to another style.
+
+---
+
+## Graphite
+
+> **New in v5.8.0** (#906)
+
+Graphite is for households that would rather the dashboard didn't shout: flat surfaces, a single hairline border instead of shadows, restrained type and a neutral palette. It reuses Clean Pro's layout and changes everything else, so the two share a shape but read very differently.
+
+Like every other style it keeps each card's `header_color`, so the family's colour coding survives the switch.
+
+---
+
+## Setting a Style Per Card
+
+Each card's visual (GUI) editor has a **Card design** dropdown with options:
+
+- *Use global default*
+- *Classic*
+- *Playroom*
+- *Console*
+- *Clean Pro*
+- *Accessible*
+- *Graphite*
+
+Or set it in YAML with the `card_design` config key:
+
+```yaml
+type: custom:taskmate-activity-card
+entity: sensor.taskmate_overview
+card_design: playroom
+```
+
+**Accepted values:** `classic | playroom | console | cleanpro | accessible | global`. An absent value (or `global`) means the card follows the global default.
+
+---
+
+## Global Default
+
+Set the default for every card from the [Admin Panel](Admin-Panel.md) → **Settings** → **Default card design** selector.
+
+
+
+Every card left on *Use global default* updates together when you change this selector. If the global default has never been set, it falls back to **Classic**.
+
+**Precedence:** a card's own `card_design` (when not `global`) wins; otherwise the card follows the global default; if neither is set, **Classic**.
+
+---
+
+## Scope & Safety
+
+- The styles apply to **all 21 TaskMate cards**.
+- Design tokens are **scoped per card** (shadow-DOM scoped), so mixing styles across a single dashboard is safe — a Console child card next to a Clean Pro rewards card both render correctly.
+- Styling never leaks into the rest of Home Assistant; only TaskMate cards are affected.
+- Each style has light and dark variants that follow your Home Assistant light/dark setting automatically.
+
+---
+
+## Accessible
+
+> **New in v5.0.0** (#704)
+
+A fifth style built for readability rather than personality. Pick it per card or as the global default, exactly like the others.
+
+- **Colour-blind safe.** Uses the Okabe-Ito palette, which stays distinguishable under protanopia, deuteranopia and tritanopia.
+- **High contrast.** Near-black on white — roughly 19:1, comfortably past WCAG AAA — with heavy borders so meaning never rests on hue alone.
+- **Dyslexia-friendly type.** Atkinson Hyperlegible, drawn for low vision: its letterforms stay distinct where similar glyphs (I/l/1, O/0) usually collapse into each other.
+- **Dark variant included.** `#0A0A0A` rather than pure black, which blooms on OLED and is harsh with astigmatism.
+
+It applies to every card, including [Routine Mode](Routine-Mode.md) and [Pre-Reader Mode](Pre-Reader-Mode.md) — the two most likely to be used by a child who needs it.
+
+---
+
+## Related
+
+- [Dashboard Cards](Dashboard-Cards.md) — all 21 cards and their config options
+- [Settings](Settings.md) — the global **Default card design** selector
diff --git a/wiki/Celebrations.md b/wiki/Celebrations.md
new file mode 100644
index 00000000..defdc6b3
--- /dev/null
+++ b/wiki/Celebrations.md
@@ -0,0 +1,122 @@
+# Celebrations
+
+Celebrations are the "big moment" layer of TaskMate. The notable things a child achieves — levelling up, hitting a streak milestone, finishing a quest, earning a perfect week — flow through one funnel that fires a single event carrying a **tier**, so a single automation can scale its reaction to the size of the moment. There's also an opt-in notification for the biggest moments.
+
+
+
+---
+
+## What Triggers a Celebration
+
+The following moments fire a celebration, each with a tier set by how big a deal it is:
+
+| Moment | Tier | Notes |
+|--------|------|-------|
+| **Level up** | 2 (medium), or 3 (epic) on every 5th level | One per level crossed — see [Levels and XP](Levels-and-XP.md) |
+| **Streak milestone** | 2 (medium), or 3 (epic) at 30+ days | See [Bonus Points](Bonus-Points.md) |
+| **Perfect week** | 3 (epic) | See [Bonus Points](Bonus-Points.md) |
+| **Quest completed** | 3 (epic) | See [Quests](Quests.md) |
+| **Challenge completed** | 2 (medium) | See [Challenges](Challenges.md) |
+| **Weekly target reached** | 2 (medium) | v6.2.0. Only on chores with a weekly target bonus. See [Weekly Targets](Weekly-Targets.md#weekly-target-bonus) |
+
+---
+
+## The Tiers
+
+Every celebration carries a numeric tier so automations can react proportionally:
+
+| Tier | Meaning |
+|------|---------|
+| `1` | Small |
+| `2` | Medium |
+| `3` | Epic |
+
+---
+
+## What Happens
+
+### The `taskmate_celebration` event (always)
+
+Every celebration fires a single `taskmate_celebration` bus event. This is the integration point for power users — wire it into automations to flash lights, play a sound, or speak a message, and use the `tier` to scale the reaction. The payload includes:
+
+| Field | Description |
+|-------|-------------|
+| `child_id` | The child the celebration is for |
+| `child_name` | The child's name |
+| `kind` | The moment type: `level_up`, `streak_milestone`, `perfect_week`, `quest_completed`, `challenge_completed`, `weekly_target_reached` |
+| `tier` | `1` (small), `2` (medium), or `3` (epic) |
+| `message` | A ready-made human-readable message |
+| `timestamp` | ISO timestamp |
+
+Some kinds add extras, e.g. `level`, `days`, `bonus`, or `quest_id` / `challenge_id` / `chore_id`, depending on the moment.
+
+Since v6.2.0 the `message` is written in Home Assistant's language (**Settings → System → General**), so a TTS automation that speaks it talks in your language too. See [Localization](Localization.md#push-notifications).
+
+### The celebration notification (opt-in)
+
+In addition to the event, a celebration can send a **notification** through TaskMate's routing system. This is **off by default** and only fires for moments at or above your chosen minimum size — so you can be alerted to the big stuff without being pinged for every small win.
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Celebration notifications** (`celebration_notify`) | off | Master toggle for the `celebration` notification |
+| **Minimum celebration size** (`celebration_notify_min_tier`) | `2` (Medium and up) | Only notify for moments at or above this tier: `1` = All, `2` = Medium and up, `3` = Epic only |
+
+Configure both in the **Admin Panel → Settings** tab. Notifications still route to whichever recipients you've enabled for the `celebration` type — see [Notifications](Notifications.md).
+
+> The minimum-size setting only gates the **notification**. The `taskmate_celebration` event always fires for every celebration regardless of tier, so automations never miss a moment.
+
+---
+
+## On-screen Celebration (Child and Kiosk Cards)
+
+Separately from the celebration funnel, the [child card](Dashboard-Cards.md) plays its own on-screen flourish — a confetti burst and a completion sound — when a child ticks off a chore, and a pop/shimmer highlight when they earn a badge. This is local card feedback for the child in front of the screen; it is driven by the card itself, not by the `taskmate_celebration` event.
+
+When a tick-off reaches a chore's [weekly target](Weekly-Targets.md#weekly-target-bonus) on a chore that doesn't need approval, the popup adds **🎉 Weekly target reached! +N** (v6.2.0).
+
+Since v6.2.0 the [Kiosk card](Kiosk-Mode.md#celebrations) gives the same feedback when a child taps **Done**: the chore's sound, confetti and the "AWESOME! You did it!" popup.
+
+---
+
+## Automation Example
+
+### Scale the reaction to the tier
+
+```yaml
+alias: TaskMate celebrations
+triggers:
+ - trigger: event
+ event_type: taskmate_celebration
+actions:
+ - choose:
+ - conditions:
+ - condition: template
+ value_template: "{{ trigger.event.data.tier == 3 }}"
+ sequence:
+ - action: light.turn_on
+ target:
+ entity_id: light.living_room
+ data:
+ flash: long
+ color_name: gold
+ - action: tts.google_translate_say
+ data:
+ entity_id: media_player.kitchen_speaker
+ message: "{{ trigger.event.data.message }}"
+ default:
+ - action: notify.family
+ data:
+ message: "{{ trigger.event.data.message }}"
+```
+
+---
+
+## Related
+
+- [Levels and XP](Levels-and-XP.md) — level-ups feed celebrations
+- [Bonus Points](Bonus-Points.md) — streak milestones and perfect weeks
+- [Quests](Quests.md) and [Challenges](Challenges.md) — completions fire celebrations
+- [Notifications](Notifications.md) — routing for the `celebration` notification type
+- [Dashboard Cards](Dashboard-Cards.md) — the child card's on-screen confetti
+- [Kiosk Mode](Kiosk-Mode.md) — the same celebrations on a shared tablet
+- [Weekly Targets](Weekly-Targets.md) — the weekly target bonus
+- [Completion Sounds](Completion-Sounds.md) — the per-chore sound played on a tick-off
diff --git a/wiki/Challenges.md b/wiki/Challenges.md
new file mode 100644
index 00000000..72386391
--- /dev/null
+++ b/wiki/Challenges.md
@@ -0,0 +1,112 @@
+# Challenges
+
+A challenge sets a recurring target — complete a number of chores today, or earn a number of points this week — and awards a one-off bonus when a child hits it. Progress and the award reset automatically each period, so challenges give kids a fresh goal every day or every week.
+
+
+
+---
+
+## How It Works
+
+Each challenge tracks a **metric** toward a **target** within a **period**:
+
+```
+Approved chores / points within the period → reaches target → bonus awarded once → resets next period
+```
+
+- Challenges count **approved** chore completions (bonus sub-task completions are excluded)
+- The `chores` metric counts completions; the `points` metric sums the points awarded by those completions within the period
+- A challenge is awarded **once per period** — the same challenge can be earned again after the period rolls over
+- Hitting the target awards the **bonus points**, fires a `taskmate_challenge_completed` event, and triggers a medium [celebration](Celebrations.md)
+
+---
+
+## Reset Cadence
+
+| Scope | Period | Resets |
+|-------|--------|--------|
+| `daily` | The current calendar day | At midnight, each new day |
+| `weekly` | Monday-anchored week | The start of each Monday |
+
+The reset is automatic — there's no scheduled job to configure. When a new period begins, progress starts from zero and the award becomes available again.
+
+---
+
+## Creating a Challenge
+
+Challenges are managed in the **Admin Panel → Challenges** tab (TaskMate's sidebar panel). There's no Settings config flow — add, edit, and delete them from the panel.
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Name** | — | Display name of the challenge (required) |
+| **Description** | `""` | Optional description |
+| **Icon** | `mdi:trophy-outline` | MDI icon |
+| **Refreshes** (`scope`) | `daily` | `daily` or `weekly` |
+| **Goal type** (`metric`) | `chores` | `chores` (completions) or `points` (points earned) |
+| **Target** | `3` | How many to reach within the period (must be at least 1) |
+| **Bonus points** | `15` | Points awarded once the target is met |
+| **Assign to** | all children | Which children the challenge applies to — leave empty for all |
+| **Active** | `true` | Inactive challenges don't track progress or award bonuses |
+
+---
+
+## Sensor Attributes
+
+Each child's entry in the `sensor.taskmate_overview` `children` attribute carries a `challenges` array. Each item describes that child's progress through one active challenge assigned to them for the current period:
+
+| Field | Description |
+|-------|-------------|
+| `challenge_id` | The challenge's ID |
+| `name` | Challenge name |
+| `icon` | Challenge icon |
+| `scope` | `daily` or `weekly` |
+| `metric` | `chores` or `points` |
+| `target` | The goal value |
+| `progress` | Current value, capped at `target` (good for progress bars) |
+| `value` | The raw current value (may exceed `target`) |
+| `bonus_points` | The bonus awarded on completion |
+| `complete` | `true` when `value >= target` |
+| `awarded` | `true` if the bonus has already been credited this period |
+
+Only **active** challenges assigned to the child appear in the array.
+
+---
+
+## Completion & Rewards
+
+When a child meets a challenge target:
+
+- The **bonus points** are credited and logged as a `Challenge complete: ` transaction
+- The bonus counts as earned points, so it also feeds the child's [XP and level](Levels-and-XP.md)
+- A `taskmate_challenge_completed` event fires with `child_id`, `child_name`, `challenge_id`, `challenge_name`, `scope`, `bonus`, and `timestamp`
+- A medium [celebration](Celebrations.md) is triggered
+
+---
+
+## Automation Example
+
+### Announce a completed challenge
+
+```yaml
+alias: Announce challenge completed
+triggers:
+ - trigger: event
+ event_type: taskmate_challenge_completed
+actions:
+ - action: notify.family
+ data:
+ message: >
+ {{ trigger.event.data.child_name }} smashed the
+ {{ trigger.event.data.scope }} challenge
+ "{{ trigger.event.data.challenge_name }}" (+{{ trigger.event.data.bonus }})!
+```
+
+---
+
+## Related
+
+- [Quests](Quests.md) — ordered chore chains that award a bonus on completion
+- [Chores](Chores.md) — completions are what challenges count
+- [Levels and XP](Levels-and-XP.md) — challenge bonuses feed XP
+- [Celebrations](Celebrations.md) — the moment fired on challenge completion
+- [Admin Panel](Admin-Panel.md) — where challenges are created and managed
diff --git a/wiki/Child-Undo-Window.md b/wiki/Child-Undo-Window.md
new file mode 100644
index 00000000..1ebd5c46
--- /dev/null
+++ b/wiki/Child-Undo-Window.md
@@ -0,0 +1,86 @@
+# Child Undo Window
+
+Children tap the wrong chore. Before, only a parent could undo it. With the **child undo window** switched on, a child can take back their own mistake: an **Undo** button appears on their card for a short while after they tick something off.
+
+
+
+> **New in v6.0.0**. Off by default.
+
+---
+
+## Turning It On
+
+**TaskMate panel → Settings → Parents (no admin rights) → Child undo window (seconds)**
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Child undo window (seconds)** | `0` | How long a child can undo an automatically approved chore, from `0` to `3600` (one hour). `0` turns child undo off. Only parents can undo. |
+
+A value between 60 and 300 seconds covers most "oops, wrong one" taps.
+
+---
+
+## What a Child Can Undo
+
+| The chore is… | The child can undo it… |
+|---------------|------------------------|
+| **Waiting for approval** | Any time until a parent reviews it. This withdraws the submission. |
+| **Approved automatically** (the chore doesn't need approval) | Within the undo window, counted from when they ticked it off. |
+| **Reviewed by a parent** (approved, or its approval undone) | Never. Only a parent can undo it. |
+
+Some completions always stay parent-only:
+
+- Chores completed while the window was `0`, including everything from before v6.0.0
+- Chores a parent completed on the child's behalf
+- Bonus ticks added from the admin panel
+
+Turning the window on later doesn't open up older completions.
+
+---
+
+## On the Child Card
+
+While a completion can be undone, the card shows an **Undo *chore name*** button near the top. It disappears on its own as soon as the window closes; the child doesn't need to refresh anything. Tapping the done chore itself (or its chip, or a done bonus sub-task) does the same thing.
+
+Once the window has passed, tapping a done chore shows the usual "Only a parent can undo a completed chore." message instead.
+
+This works in every card design, in pre-reader (picture) mode, and on the [routine card](Routine-Mode.md), where a step you've just finished shows **Undo** while the window allows it.
+
+Parents tapping a done chore still reject it as before.
+
+---
+
+## What Undo Reverses
+
+A child's undo reverses the completion completely: the points, the chore count, the streak and the leaderboard score all go back to how they were. Bonus sub-tasks completed on that chore are undone with it.
+
+---
+
+## Who Can Undo Whose Chore
+
+The new `taskmate.undo_chore` service works out the child from the completion itself, not from the caller. Then it applies the usual linked-account rule for that child:
+
+- A child can't undo a sibling's chore.
+- With **Require a linked account per child** switched on, only the child's own Home Assistant user (or an admin) can undo it.
+- The window applies to everyone using this route, admins included. Parents keep their own undo and reject buttons for anything outside the window.
+
+```yaml
+action: taskmate.undo_chore
+data:
+ completion_id: f5548687
+```
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `completion_id` | Yes | The completion to undo |
+
+A child's undo fires `taskmate_chore_undone` rather than `taskmate_chore_rejected`, so your automations can tell the two apart.
+
+---
+
+## Related
+
+- [Parent Access](Parent-Access.md) — what parents and children can each do
+- [Approvals Card](Approvals-Card.md) — how parents review and undo chores
+- [Reject Reasons](Reject-Reasons.md) — sending a chore back with an explanation
+- [Services](Services.md) — full service reference
diff --git a/wiki/Children.md b/wiki/Children.md
new file mode 100644
index 00000000..6e0c12ab
--- /dev/null
+++ b/wiki/Children.md
@@ -0,0 +1,167 @@
+# Children
+
+## Managing Children
+
+
+
+Access via the **TaskMate** panel → **Children**.
+
+---
+
+## Child Fields
+
+| Field | Description |
+|-------|-------------|
+| **Name** | Display name shown on all cards |
+| **Avatar** | MDI icon shown in the card header |
+| **Photo from** | *(v6.4.0)* Optional entity whose picture is shown instead of the avatar icon, usually the child's `person` entity. See [Child Photos](#child-photos) below. |
+| **Adult profile** | *(v6.4.0)* Marks the profile as a grown-up's: their chores are approved straight away, and family-wide cards leave them out unless asked. See [Adult Profiles](Adult-Profiles.md). |
+| **Availability Entity** | Optional HA entity (e.g. a `binary_sensor` or `input_boolean`). When the entity's state is not in the recognised "available" set, the child is treated as unavailable — chores with **Require Availability** enabled will skip them in rotation. |
+| **Availability Inverted** | Flips the availability logic — when enabled, recognised "available" states (`on`, `home`, `available`, `present`, `true`) mean the child is **unavailable** instead. Useful for entities like `binary_sensor.child_at_school` where `on` means the child is away. |
+| **Unavailability Entity** | Optional second HA entity for a busy/away state (e.g. a school calendar sensor). When this entity's state is in the "available" set, the child is treated as **busy**. Combined logic: `final_available = availability_ok AND NOT busy`. |
+| **Quiet Hours** | Optional per-child do-not-disturb window. While the local time is inside the window, this child's notifications are held back. Set in the Notifications tab. See [Quiet Hours](Quiet-Hours.md). |
+
+---
+
+## Levels & XP (v4.0.0)
+
+Every child has an **XP level** derived from their `total_points_earned` (lifetime points). XP is never spent — claiming rewards reduces the spendable `points` balance but never lowers the level. Levels rise as the child keeps earning.
+
+- Level formula: `level = (total_points_earned // level_xp_step) + 1` — level 1 starts at 0 XP
+- `level_xp_step` is the **XP per Level** setting (default `100`); see [Settings](Settings.md)
+- The overview sensor exposes `level`, `level_progress` (XP into the current band), and `level_target` per child
+- Crossing a level boundary on chore approval fires a level-up [celebration](Celebrations.md) (every 5th level is an "epic" tier)
+
+See [Levels and XP](Levels-and-XP.md) for the full mechanics.
+
+---
+
+## Avatar Options
+
+A child's avatar is shown in card headers and on the stats sensor icon. There are two ways an avatar can be set:
+
+1. **Parent assignment** — from the [Admin Panel](Admin-Panel.md) a parent can set any avatar (a free-form MDI icon or any catalogue avatar), bypassing unlock requirements.
+2. **Child self-service via the avatar catalogue (v4.0.0 unlockables)** — children pick from the avatar catalogue, but only avatars they have **unlocked** are selectable. The `taskmate.choose_avatar` service enforces the unlock requirement.
+
+### Avatar unlockables (v4.0.0)
+
+The catalogue is exposed per child in the overview sensor's `children[].avatar_options`, each entry carrying `id`, `label`, `icon`, `unlocked`, and a human-readable `requirement`. Unlock gates are one of:
+
+| Gate type | Unlocks when | Example `requirement` text |
+|-----------|--------------|----------------------------|
+| `free` | Always available | (empty) |
+| `level` | Child's [level](Levels-and-XP.md) ≥ threshold | `"Level 5"` |
+| `points` | `total_points_earned` ≥ threshold | `"500 earned"` |
+| `streak` | `best_streak` ≥ threshold | `"7-day streak"` |
+
+The shipped default catalogue includes a free starter avatar plus level-, points-, and streak-gated avatars (for example a rocket at level 3, a robot at level 5, a ninja at level 10, a crown at 500 points earned, a trophy at 1000 earned, a fire at a 7-day streak, and a diamond at a 30-day streak). See [Avatars](Avatars.md) for the full default catalogue and how parents customise it.
+
+### Free-form MDI icons
+
+When a parent sets an avatar directly, any valid MDI icon can be used. TaskMate also ships a large selection of themed icons:
+
+| Category | Examples |
+|----------|---------|
+| Basic faces | `mdi:account-circle`, `mdi:face-man`, `mdi:face-woman` |
+| Fun characters | `mdi:robot-happy`, `mdi:ninja`, `mdi:pirate`, `mdi:alien` |
+| Animals | `mdi:unicorn`, `mdi:dragon`, `mdi:panda`, `mdi:fox`, `mdi:penguin`, `mdi:koala`, `mdi:dolphin`, `mdi:octopus` |
+| Expressive | `mdi:emoticon-cool`, `mdi:emoticon-excited`, `mdi:emoticon-wink`, `mdi:star-face` |
+| Gaming | `mdi:crown`, `mdi:trophy`, `mdi:rocket`, `mdi:sword`, `mdi:shield`, `mdi:lightning-bolt` |
+| Space/Fantasy | `mdi:ghost`, `mdi:wizard-hat`, `mdi:ufo`, `mdi:dragon` |
+| Nature | `mdi:mushroom`, `mdi:butterfly`, `mdi:flower-tulip`, `mdi:star-shooting` |
+
+Any valid MDI icon can be entered manually if you want something not in the list.
+
+---
+
+## Child Photos
+
+> **New in v6.4.0** — contributed by @cad861
+
+A child's face can be a real photo instead of an icon. In the child dialog, set **Photo from** to the child's `person` entity (or any entity with a picture), and every TaskMate card shows that picture wherever it would show the avatar. Home Assistant's own UI shows it on the child's stats sensor too.
+
+- **Set the photo in Home Assistant.** A person's picture is set under **Settings → People**. TaskMate stores only which entity to use and reads the picture from it each time, so a new photo shows up without saving anything in TaskMate.
+- **The icon is the fallback.** If the entity has no picture, or is removed, the cards show the child's avatar icon as before. Children with no **Photo from** set are unchanged.
+- **It's separate from the user link.** A young child often has a person with a photo but no Home Assistant login of their own, so the photo doesn't depend on **Link to Home Assistant user**.
+- TaskMate's own child sensors can't be picked, since they show the photo themselves.
+
+The picture is published as `avatar_image` on the overview sensor's `children` list and on each child's points, stats and badges sensors (empty when there is none). See [Sensor Attributes](Sensor-Attributes.md#children-entries).
+
+---
+
+## Child Data
+
+Each child stores the following data internally:
+
+| Field | Description |
+|-------|-------------|
+| `id` | Unique 8-character ID (auto-generated) |
+| `name` | Display name |
+| `avatar` | MDI icon string |
+| `availability_entity` | Optional HA entity ID for availability tracking |
+| `availability_inverted` | Whether availability logic is flipped |
+| `unavailability_entity` | Optional second HA entity for busy state |
+| `points` | Current available points balance |
+| `total_points_earned` | All-time points earned (never decreases) |
+| `total_chores_completed` | All-time chore completion count |
+| `current_streak` | Current consecutive days streak |
+| `best_streak` | Best streak ever achieved |
+| `last_completion_date` | ISO date of most recent chore completion |
+| `streak_paused` | Whether streak is paused (pause mode only) |
+| `chore_order` | Custom chore display order for the child |
+| `streak_milestones_achieved` | List of milestone day counts already rewarded |
+| `awarded_perfect_weeks` | List of Monday dates for awarded perfect weeks |
+| `career_score` | Long-term performance metric (`total_points_earned − total_penalties_received`) |
+| `total_penalties_received` | Lifetime count of penalties applied |
+| `level` | (v4.0+) Cached XP level derived from `total_points_earned`. See [Levels and XP](Levels-and-XP.md) |
+| `linked_user_id` | (v4.0+) HA user ID linked to this child; when set, only that user (or an admin) may self-serve as this child |
+| `notify_service` | Optional per-child `notify.*` service override |
+| `quiet_hours_start` | (v4.4+) Start of the do-not-disturb window in `HH:MM` (24h); empty = disabled. See [Quiet Hours](Quiet-Hours.md) |
+| `quiet_hours_end` | (v4.4+) End of the do-not-disturb window in `HH:MM` (24h, exclusive); a start later than the end is an overnight window. See [Quiet Hours](Quiet-Hours.md) |
+| `picture_entity` | (v6.4+) Entity whose picture replaces the avatar icon; empty = use the icon. See [Child Photos](#child-photos) |
+| `is_adult` | (v6.4+) `true` for an [adult profile](Adult-Profiles.md) |
+
+---
+
+## Editing a Child
+
+1. Open the **TaskMate** panel → **Children** — select the child from the list
+2. Change the name or avatar
+3. **Save** the change, or use **Delete** to remove the child
+
+> **Warning:** Deleting a child is permanent. Their completion history, points, and streaks are removed. The chores they were assigned to are not deleted.
+
+---
+
+## Chore Order
+
+The order chores appear on the Child Card can be customised per child using the **Reorder Card** or the `taskmate.set_chore_order` service. The order is stored on the child record, so each child can have a different chore display order.
+
+---
+
+## Logging a Past Job
+
+Each child's profile card has a **Log a past job** button for a job done on an earlier day that nobody ticked at the time. See [Logging Past Jobs](Logging-Past-Jobs.md).
+
+---
+
+## Points Balance
+
+A child's `points` balance is their **spendable** balance — it decreases when a reward claim is approved. `total_points_earned` is a running lifetime total that only ever increases, used for leaderboard rankings and for driving the child's [level/XP](Levels-and-XP.md) and [avatar unlocks](Avatars.md).
+
+Pending reward claims reserve points but do not deduct them until the parent approves.
+
+---
+
+## Related
+
+- [Levels and XP](Levels-and-XP.md) — how lifetime points drive levels
+- [Avatars](Avatars.md) — avatar catalogue and unlock requirements
+- [Quiet Hours](Quiet-Hours.md) — the per-child do-not-disturb window
+- [Birthday Mode](Birthday-Mode.md) — bonus points, a badge and an optional day off on a child's birthday
+- [Guest Child Profiles](Guest-Child-Profiles.md) — temporary profiles for visitors that expire on their own
+- [Adult Profiles](Adult-Profiles.md) — profiles for parents who log their own chores
+- [Logging Past Jobs](Logging-Past-Jobs.md) — record a job done on an earlier day that nobody ticked
+- [Kiosk Mode](Kiosk-Mode.md) — a shared wall tablet, with an optional PIN per child
+- [Settings](Settings.md) — XP-per-level and other per-family settings
+- [Sensor Reference](Sensor-Reference.md) — per-child sensor attributes
diff --git a/wiki/Chore-Auctions.md b/wiki/Chore-Auctions.md
new file mode 100644
index 00000000..91009d52
--- /dev/null
+++ b/wiki/Chore-Auctions.md
@@ -0,0 +1,117 @@
+# Chore Auctions
+
+Nobody wants to clean the bathroom. So let the children bid for it. A **chore auction** puts one day's occurrence of a chore up for sealed bids, where each child names the *fewest* points they'd do it for. The lowest bid wins the job at their price. The unpopular chore gets done, and the child who minds it least is the one who does it.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## How It Works
+
+1. **You open an auction** on one occurrence of an existing chore, for example "Clean the bathroom, Saturday 3 October". You set a maximum price, when bidding closes, and which children can bid.
+2. **Children place sealed bids** on their Auction card: the fewest points they'd accept, up to your maximum. They can change or withdraw their bid until it closes.
+3. **Bidding closes.** The lowest bid wins. If two children bid the same amount, the earlier bid wins.
+4. **The winner gets that day's chore at their price.** It appears on their card with a **Won at auction** tag and their winning price as its points, and goes through the normal completion and approval flow.
+
+If nobody bids, the chore simply stays on its normal assignment for that day, and you can re-open the auction with a higher maximum.
+
+---
+
+## Keeping Bids Secret
+
+Children only ever see how many bids are in, never anyone else's amount. After closing they see the winner and the winning price, and a child who lost on a tie is told that's why.
+
+Changing a bid moves it to the back of the queue for tie-breaks, so there's no advantage in bidding high early and then undercutting at the last second. Re-entering the same number keeps its place.
+
+Parents can see every bid on the **Auctions** page (turn off **Show bid amounts** if you'd rather not see them). Notifications and automation events never include bid amounts.
+
+---
+
+## Starting an Auction
+
+**TaskMate panel → Auctions → Start an auction**. Or use **New → Auction**, or **Auction an occurrence** in a chore's ⋮ menu on the Chores page.
+
+
+
+| Field | Description |
+|-------|-------------|
+| **Chore** and **Which one** | The chore, and which of its upcoming days (up to 60 days ahead) to auction. Only that day is auctioned; the rest of the schedule is unchanged |
+| **Maximum bid** | The most anyone can bid. The chore's normal points are shown alongside for reference |
+| **Minimum bid** | Off by default, so any bid from 1 counts. Turn it on to stop a race to the bottom |
+| **Closes** | Quick picks (tonight 19:00, tomorrow 08:00, the day before at 18:00) or a time you choose. Bidding must close before the chore's day |
+| **Who can bid** | Which of the chore's children may bid |
+| **Tell children it's open** | Sends the *Auction opened* notification |
+
+The page lists **Live** and **Closed** auctions, with **Close now**, cancel and delete on each row, and **Re-open with a higher max** on one that closed without bids. The row menu entry lives with the other chore actions:
+
+
+
+### What can't be auctioned
+
+- Teamwork, timed, open-ended and unassigned chores
+- A day that already has a live (or won) auction
+- A day that has already started
+
+Auctions are one-offs: there are no repeating auctions.
+
+---
+
+## After the Auction
+
+- **The price.** The winner's completion that day pays their winning bid instead of the chore's usual points. Streak and weekend multipliers still apply on top, as they would to any chore.
+- **Everyone else.** The chore is hidden from every other child that day, even on an "everyone" chore, and rotation and reminders follow the winner.
+- **If the winner doesn't do it**, it's an ordinary missed chore. There's no extra penalty.
+- **Calendar.** The won day shows on the winner in the Home Assistant calendar, the calendar card and the ICS feed, with the winning price, ahead of the day.
+- **Moving the day** on the calendar takes the win with it. Cancelling the auction, deleting the chore or removing the winner puts the chore back to normal.
+- **Clean-up.** Finished auctions can be deleted from the Closed list, are tidied away with the rest of the history, and are removed when their chore is deleted.
+
+---
+
+## The Card
+
+Each child has their own view: a gauge of the maximum price, a sealed-bid box with their current bid, a bid sheet with a slider and a keypad, the closing countdown and the number of other bids. Results stay on the card for 24 hours.
+
+```yaml
+type: custom:taskmate-auction-card
+entity: sensor.taskmate_overview
+child_id: b803da068e6a4b21
+```
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `entity` | string | **required** | The TaskMate overview sensor |
+| `child_id` | string | **required** | Whose auctions and bids the card shows. Find IDs in the panel with **Show IDs** switched on |
+| `title` | string | `Chore Auction` | Card header title |
+| `card_design` | string | global default | `classic`, `playroom`, `console`, `cleanpro`, `accessible` or `graphite` |
+| `header_color` | string | `#5e35b1` | Header banner colour |
+
+---
+
+## Notifications
+
+All three are off until you switch them on under **Notifications**:
+
+| Type | Sent to | When |
+|------|---------|------|
+| **Auction opened** | The children who can bid | An auction starts with *Tell children it's open* on |
+| **Closing within the hour** | The children who can bid | One hour before bidding closes |
+| **Result** | The children who could bid, and parents | Bidding closes, or a live auction with bids is cancelled |
+
+---
+
+## Sensor and Events
+
+`sensor.taskmate_auctions` carries a digest of live and recent auctions: counts, and the winner and price once closed. It never includes bid amounts.
+
+Events: `taskmate_auction_opened`, `_bid`, `_bid_withdrawn`, `_closed` and `_cancelled`. None of them carry a bid amount.
+
+---
+
+## Related
+
+- [Bounty Board](Bounty-Board.md) — one-off jobs at a fixed price, first to claim
+- [Chore Scheduling](Chore-Scheduling.md) — how a chore's normal assignment works
+- [Chore Swaps](Chore-Swaps.md) — children trading a chore between themselves
+- [Calendar](Calendar.md) — where won days show up
diff --git a/wiki/Chore-Dependencies.md b/wiki/Chore-Dependencies.md
new file mode 100644
index 00000000..63a2ac48
--- /dev/null
+++ b/wiki/Chore-Dependencies.md
@@ -0,0 +1,78 @@
+# Chore Dependencies
+
+Chore dependencies let you chain chores together so one only becomes available after others are finished. A chore with dependencies stays locked until **every** chore it depends on has been completed and approved **today** by the **same child** — then it unlocks for that child.
+
+
+
+This turns a loose list of chores into an ordered routine: tidy the room *before* vacuuming, clear the table *before* loading the dishwasher.
+
+---
+
+## How It Works
+
+Each chore can list one or more **prerequisite chores** it depends on (the `depends_on` field — a list of chore IDs). The dependent chore is only available to a child when **all** of its prerequisites are satisfied for that child:
+
+- Each prerequisite must have an **approved** completion (a pending, not-yet-approved completion does not count).
+- The completion must have been made **today**, by the **same child** who is trying to do the dependent chore.
+- Parent chore completions count; bonus sub-task completions do **not**.
+
+Because the check is evaluated **per day**, dependencies reset every night. Yesterday's approved prerequisites don't carry over — the child has to work back up the chain each day. If a prerequisite is rejected (or an approval is undone), the dependent chore locks again until the prerequisite is re-completed and re-approved.
+
+---
+
+## Setting Dependencies
+
+Open the chore editor in the **Admin Panel → Chores → Edit chore**. Below the assignment options there's a **"Depends on"** picker listing your other chores. Tap a chore to mark it as a prerequisite; tap again to remove it. (A chore can't depend on itself, so it never appears in its own list.)
+
+The editor hint sums it up: *"This chore stays hidden until the selected chores are approved for the child today."*
+
+You can select several prerequisites — they must **all** be satisfied before the dependent chore unlocks.
+
+---
+
+## Effect on Availability and Visibility
+
+Dependencies are one more gate on top of everything else that decides whether a child sees a chore. A chore that is scheduled and due today can still be **locked** purely because its prerequisites aren't done yet. Dependencies are checked alongside:
+
+- The chore's schedule (see [Chore Scheduling](Chore-Scheduling.md)) — a dependent chore must still be due today *and* have its prerequisites met.
+- Rotation assignment, vacation/away status, and per-child disabling.
+- Any [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) entity condition.
+
+While locked, how the dependent chore appears is controlled by the child card's **`dependency_mode`** option:
+
+| Value | Behaviour |
+| --- | --- |
+| `hide` *(default)* | The chore isn't shown at all until it unlocks. Matches the backend, which simply reports it unavailable. |
+| `dim` | Shown greyed out and not tappable, with a **"Do *X* first"** note naming the prerequisite, so the child can see what unlocks it. |
+| `show` | Shown at normal opacity, still not tappable. |
+
+Set it in the card editor under **Chores Waiting On Another**, or in YAML:
+
+```yaml
+type: custom:taskmate-child-card
+entity: sensor.taskmate_overview
+child_id:
+dependency_mode: dim
+```
+
+Under every mode the tap is refused, on all six card designs and in picture mode — the backend would reject the completion anyway. Once the last prerequisite is approved, the chore unlocks for the child on the next refresh.
+
+---
+
+## Example
+
+A bedtime routine, all assigned to the same child:
+
+1. **Tidy room** — no dependencies, available from the start of the day.
+2. **Vacuum** — depends on *Tidy room*. Hidden until Tidy room is approved.
+3. **Put out pyjamas** — depends on *Vacuum*. Hidden until Vacuum is approved.
+
+The child can only ever see the next step in the chain, in order, and only after a parent has approved the previous one — each day afresh.
+
+---
+
+## Related
+
+- [Chores](Chores.md) — the chore editor and the full list of chore fields
+- [Chore Scheduling](Chore-Scheduling.md) — how a chore becomes due in the first place
+- [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) — gating a chore on a Home Assistant entity state
diff --git a/wiki/Chore-Roulette.md b/wiki/Chore-Roulette.md
new file mode 100644
index 00000000..21d4ecbb
--- /dev/null
+++ b/wiki/Chore-Roulette.md
@@ -0,0 +1,65 @@
+# Chore Roulette
+
+An opt-in nudge for the child who has stalled: spin once, get a random outstanding chore, and earn a multiplier on it if they do it.
+
+
+
+It is a way of turning "I don't know where to start" into one specific thing worth extra.
+
+---
+
+## Turning It On
+
+Roulette is **doubly opt-in** — it needs both a global setting and a card setting, so an existing dashboard never sprouts a new button unasked.
+
+1. **Settings** — enable roulette (off by default), and set the multiplier and how many spins a child gets per day.
+2. Add `show_roulette: true` to the child card:
+
+```yaml
+type: custom:taskmate-child-card
+entity: sensor.taskmate_overview
+child_id:
+show_roulette: true
+```
+
+---
+
+## Key Points
+
+- **Roulette only ever picks a chore the child is actually allowed to do right now.** It runs the same availability check as everything else, so the [weather gate](Weather-Aware-Chores.md), [deadlines](Reactive-Chores.md), [dependencies](Chore-Dependencies.md) and rotation are all respected.
+- The pick is recorded **per child, per day**. It survives a reload, can't be re-rolled past the daily allowance, and expires overnight.
+- **A re-spin moves to a different chore** where one is available, rather than handing back the same one.
+- The multiplier is applied **at completion**, and stacks with the [difficulty](Difficulty-Tiers.md) multiplier and any [speed bonus](Reactive-Chores.md).
+- **A multiplier below 1 is clamped to 1.** Spinning should never punish the child for trying.
+- The spin button renders under **all six** [card design styles](Card-Design-Styles.md), taking its colour from the active design's accent.
+
+---
+
+## Spinning from an Automation
+
+Children spin via the `taskmate.spin_roulette` service, which the card calls for them:
+
+```yaml
+action: taskmate.spin_roulette
+data:
+ child_id:
+```
+
+Spinning fires `taskmate_roulette_spun`:
+
+| Field | Meaning |
+|-------|---------|
+| `child_id` / `child_name` | Who spun |
+| `chore_id` / `chore_name` | What they landed on |
+| `multiplier` | The multiplier that will apply |
+| `timestamp` | When |
+
+---
+
+## Related
+
+- [Chores](Chores.md) — what makes a chore available to be picked
+- [Difficulty Tiers](Difficulty-Tiers.md) — the other multiplier, which stacks with this one
+- [Reactive Chores](Reactive-Chores.md) — speed bonuses, which also stack
+- [Services](Services.md) — the full `taskmate.spin_roulette` signature
+- [Settings](Settings.md) — the global roulette settings
diff --git a/wiki/Chore-Scheduling.md b/wiki/Chore-Scheduling.md
new file mode 100644
index 00000000..ba82ae90
--- /dev/null
+++ b/wiki/Chore-Scheduling.md
@@ -0,0 +1,293 @@
+# Chore Scheduling
+
+TaskMate supports three scheduling modes for chores — specific days, recurring, and one-shot — set in the chore dialog. A separate **assignment** mode decides *who* gets a chore; see [Assignment Modes](Chores.md#assignment-modes).
+
+
+
+> **Note:** Whatever the schedule, a chore's availability can additionally be gated by [Chore Dependencies](Chore-Dependencies.md). A chore that is scheduled and due today may still stay locked until its prerequisite chores are completed and approved for that child today.
+
+---
+
+## Mode A — Specific Days
+
+The chore appears on selected days of the week. This is the default mode and matches the existing behaviour.
+
+**Setup:** In the chore dialog, select which days the chore should appear. Leave empty to show every day.
+
+**Child card behaviour:** Use `due_days_mode` on the child card:
+- `hide` — chores not due today are hidden entirely
+- `dim` — chores not due today are shown greyed out and non-interactive
+- `show` — all chores shown regardless of day
+
+**Progress counting:** The Overview card and Parent Dashboard count only chores due today in the progress bar denominator — a chore scheduled Mon/Wed/Fri doesn't inflate Saturday's total.
+
+---
+
+## Mode B — Recurring
+
+The chore has a rolling recurrence window. Once completed, it cannot be done again until the window expires.
+
+**Setup:** Select **Recurring** as the schedule mode, then configure:
+
+| Field | Applies To | Description |
+|---|---|---|
+| **Recurrence** | All | How often the chore can be completed |
+| **Repeat every (days)** | Every N days (custom) | *(v6.2.0)* The interval, a whole number of days from 2 to 365. Replaces the Day of Week field when this option is picked. |
+| **Day of Week** | Weekly, Every 2 Weeks | Pin to a specific day. Leave empty for any day. |
+| **Start Date** | Every 2 Days, Every N days | Anchor date for the rhythm. See [Every N Days](#every-n-days-custom) for how it works. |
+| **First Occurrence** | All | Available immediately or wait for first scheduled occurrence |
+
+### Recurrence Windows
+
+| Option | Window |
+|---|---|
+| Every 2 days | 2 days from last completion date |
+| Every N days (custom) | N days from last completion date, N from 2 to 365 (v6.2.0) |
+| Weekly | 7 days from last completion date |
+| Every 2 weeks | 14 days from last completion date |
+| Monthly | 30 days from last completion date |
+| Every 3 months | 90 days from last completion date |
+| Every 6 months | 180 days from last completion date |
+
+### Every N Days (custom)
+
+> **New in v6.2.0**
+
+When none of the fixed options fit, pick **Every N days (custom)** and set **Repeat every (days)** to any whole number from **2 to 365**: towels every 3 days, plants every 5, a deep clean every 10.
+
+
+
+**TaskMate panel → Chores → edit a chore → Schedule mode: Recurring → Recurrence: Every N days (custom) → Repeat every (days)**
+
+- **No start date:** the chore opens again N days after it was last done, so the rhythm moves with the child.
+- **With a start date:** the chore is pinned to fixed days, the start date and every N days after it (5 Oct, 10 Oct, 15 Oct, …). Before the start date it stays locked. Once it has been done, it only opens again on one of those days, and can be done once that day.
+
+The panel won't save a number outside 2–365 and shows a message instead. *Every 2 days* is the same thing as *Every N days* with N = 2. The Chores list shows the schedule as "Every 5 days", and so does the child card.
+
+> The Start date field is still labelled *(every-2-days only)* in the editor. It applies to Every N days too.
+
+Windows are **midnight-rounded** — if completed at 7pm Wednesday, the window starts from Wednesday midnight. A weekly chore completed Wednesday is available again the following Wednesday from midnight.
+
+### First Occurrence Mode
+
+When a recurring chore is first created (no completions yet):
+
+| Setting | Behaviour |
+|---|---|
+| **Available Immediately** (default) | Child can complete it straight away |
+| **Wait for First Scheduled Occurrence** | Chore is locked until the first scheduled day/date arrives |
+
+For **Weekly/Every 2 Weeks** with a Day of Week set — "wait" means locked until that day of the week arrives.
+
+For **Every 2 Days** or **Every N days** with a Start Date, the chore is locked until the start date (whatever this setting says).
+
+For **Monthly and longer** — "wait" means locked for the full window from creation date before first use.
+
+### Child Card Display
+
+Use `recurrence_done_mode` on the child card to control what happens when a recurring chore is completed and waiting to reset:
+
+| Value | Behaviour |
+|---|---|
+| `dim` | Shown greyed out, non-interactive (default) |
+| `hide` | Hidden entirely until available again |
+| `show` | Shown normally — child can see it's done but can't complete again |
+
+### Undo Behaviour
+
+If a child undoes a recurring chore completion, the **previous** completion becomes the window anchor — the chore does not immediately become available again (unless there was no previous completion). This prevents gaming the system by repeatedly completing and undoing to reset the window.
+
+### Last Completed Store
+
+Recurrence windows are tracked in a dedicated store separate from the prunable completion history. This means:
+- The `history_days` setting does not affect recurrence — a 6-month chore will still be correctly locked even if history is set to 90 days
+- The store keeps only the two most recent completions per chore per child — current and previous (for undo)
+
+---
+
+## Mode C — One-Shot (Non-Recurring)
+
+A one-shot chore is a single-use task that is valid only for the day it is created. Once completed and approved (or once midnight passes), the chore soft-disables itself. This is ideal for non-routine tasks that deserve a reward but don't happen on a schedule.
+
+**Use cases:**
+- "Help wash the car" — sunny Saturday task
+- "Big bedroom declutter" — one-time project
+- "Help with groceries" — spontaneous reward opportunity
+
+### Setup
+
+1. Open the **TaskMate** panel → **Chores** → **+ Add chore**
+2. Fill in the chore details (name, points, etc.)
+3. For **Schedule Mode**, select **"One-time task (single day)"**
+4. The chore is created immediately — no second scheduling step is needed
+
+> **Note:** `daily_limit` is automatically forced to `1` for one-shot chores.
+
+### Lifecycle
+
+```
+Creation (today)
+ │
+ ├─ Child completes it
+ │ ├─ requires_approval = off → points awarded, chore disables for this child
+ │ └─ requires_approval = on → pending approval
+ │ ├─ Parent approves → points awarded, chore disables for this child
+ │ └─ Parent rejects → chore re-enables for this child (they get another shot)
+ │
+ └─ Midnight arrives (00:00:05)
+ └─ Chore auto-disables if still enabled (not completed)
+```
+
+
+### Soft-Disable Behaviour
+
+One-shot chores use **soft-disabling** rather than deletion:
+
+| Field | Purpose |
+|-------|---------|
+| `enabled` | `false` when the chore is globally disabled (all children done or expired) |
+| `disabled_for` | List of child IDs for whom this chore is individually disabled |
+| `created_date` | ISO date (e.g. `2026-04-16`) — the chore is only available on this date |
+
+Disabled chores remain in storage for history and audit purposes. Points and completion records are preserved.
+
+### Multi-Child Behaviour
+
+When a one-shot chore is assigned to multiple children:
+
+- Each child gets their **own independent shot** at completing it
+- When child A completes and gets approved, the chore disables **only for child A**
+- Child B can still see and complete the chore
+- The chore becomes **globally disabled** (`enabled = false`) only when **all** assigned children have completed it
+- If `assigned_to` is empty (all children), the system checks against all children in the system
+
+### Re-Enabling a One-Shot Chore
+
+Parents can re-use a one-shot chore at a later date:
+
+1. Open the **TaskMate** panel → **Chores** — disabled chores show **(disabled)** next to their name
+2. Open the disabled chore's **⋮** menu
+3. Choose **Activate chore**
+4. The chore re-enables with today's date as the new `created_date`
+
+This effectively gives the chore a fresh 1-day window. The same chore definition (name, points, assignment) is reused without creating a duplicate.
+
+### Midnight Expiry
+
+One-shot chores that are not completed by end of day are automatically soft-disabled at **00:00:05** by the same midnight callback that handles streak checks. This ensures the active chore list stays clean without manual intervention.
+
+- Already-disabled chores are skipped (no double-processing)
+- Non-one-shot chores are unaffected
+- A log entry is written: `One-shot chore '' expired (created , today )`
+
+### Rejection Handling
+
+When a parent rejects a one-shot completion:
+
+1. The child is removed from `disabled_for`
+2. The chore's `enabled` flag is set back to `true`
+3. Points are reversed (same as any other rejection)
+4. The chore reappears on the child's card — they can try again (as long as it's still the same day)
+
+### Child Card Display
+
+One-shot chores follow the same filtering as other chores:
+
+- If `enabled = false` → hidden for all children
+- If child's ID is in `disabled_for` → hidden for that child
+- If `created_date ≠ today` → hidden (expired)
+- Otherwise → shown normally
+
+The parent dashboard applies the same filters.
+
+
+---
+
+## First Come First Served
+
+`first_come` is a competitive assignment mode: instead of giving today's turn to one child, the chore is shown to the **whole pool** and the first child to complete it wins. Set it in the **Assignment Mode** selector on the chore (see [Assignment Modes](Chores.md#assignment-modes)).
+
+### How It Works
+
+- **Shown to everyone in the pool** — every assigned child (or all children, if `assigned_to` is empty) sees the chore until it is claimed. With **Require Availability** on, only currently-available children see it.
+- **Single winner** — the first completion fills a shared quota of one and **locks the chore for the whole pool** for the rest of the day. The daily limit is always treated as `1` for first-come chores regardless of any configured value.
+- **Race losers** — if another child tries to complete it after it has been claimed, the attempt is rejected with *"Chore '…' was already completed by another child."* No points are awarded to the loser.
+- **Daily reset** — the lock is per-day; the chore opens up to the pool again the next day.
+
+### Panel Behaviour
+
+- In the chore dialog, the **Daily Limit** field is hidden for first-come chores (the limit is fixed at 1).
+- First-come chores carry a gold **First come** badge in the chore list.
+- First-come chores are **excluded from [Task Groups](Task-Groups.md)** — the group dialog won't list them — and from per-child rotation bookkeeping, because there is no single assignee to coordinate.
+
+### Card Behaviour
+
+By default a claimed first-come chore vanishes from every card in the pool — **including the winner's**, so there is no confirmation it was done and no way to see who got there first.
+
+From **v5.4.0** the child card's `first_come_claimed_mode` option changes that:
+
+| Value | Behaviour |
+|-------|-----------|
+| `hide` | **Default.** The row disappears for everyone once claimed (behaviour before v5.4.0) |
+| `dim` | The row stays, greyed out and not tappable |
+| `show` | The row stays at full opacity, still not tappable |
+
+Under `dim` and `show`, the winner keeps their normal completed row with undo, and everyone else sees a locked row reading *"Already done by {name}"*. A pool-wide dismissal from the admin panel has no single winner, so every child sees *"Already claimed today"* rather than it appearing as done for all of them.
+
+Set it in the card editor under **First-Come Chores — When Claimed**, or in YAML — see [Dashboard Cards](Dashboard-Cards.md#child-card).
+
+> **Not covered:** timed-task cards and pre-reader tiles don't check this lock, so a claimed first-come chore stays live and tappable in those two views. A tap there is still rejected by the backend as a race loser.
+
+> The badge/short label shown in the panel is "First come"; the full mode description reads *"First come — first child to finish wins; it hides for the rest."*
+
+---
+
+## Sensor Attributes
+
+Each chore in `sensor.taskmate_overview` → `chores` exposes:
+
+| Attribute | Description |
+|-----------|-------------|
+| `schedule_mode` | `specific_days`, `recurring`, or `one_shot` |
+| `recurrence` | e.g. `weekly`, `every_2_weeks`, or `every_5_days` for a custom Every N days chore (v6.2.0) |
+| `recurrence_day` | e.g. `tuesday` (if pinned) |
+| `recurrence_start` | ISO date anchor (Every 2 Days / Every N days) |
+| `first_occurrence_mode` | `available_immediately` or `wait_for_first_occurrence` |
+| `enabled` | `true` / `false` — whether the chore is active (one-shot soft-disable) |
+| `disabled_for` | List of child IDs this chore is individually disabled for |
+| `created_date` | ISO date — creation date used for one-shot expiry |
+| `is_available` | `{ child_id: bool }` — pre-calculated availability per child |
+| `last_completed_at` | `{ child_id: ISO datetime }` — most recent completion per child |
+
+The `is_available` attribute is pre-calculated by the backend so cards don't need to implement window logic themselves. For one-shot chores, `is_available` accounts for `enabled`, `disabled_for`, and `created_date`.
+
+---
+
+## Configurable Time-of-Day Boundaries
+
+> **Available in:** v3.6.0+
+
+The time windows for morning, afternoon, evening, and night are configurable via the admin panel under **Settings**. These boundaries affect calendar event windows when chores are published to HA calendar entities.
+
+### Defaults
+
+| Category | Start | End |
+|----------|-------|-----|
+| Morning | 06:00 | 12:00 |
+| Afternoon | 12:00 | 17:00 |
+| Evening | 17:00 | 21:00 |
+| Night | 21:00 | 23:59 |
+| Anytime | — | — (all-day event) |
+
+### Settings
+
+| Setting | Format | Description |
+|---------|--------|-------------|
+| `time_morning_start` / `time_morning_end` | `HH:MM` | Morning window boundaries |
+| `time_afternoon_start` / `time_afternoon_end` | `HH:MM` | Afternoon window boundaries |
+| `time_evening_start` / `time_evening_end` | `HH:MM` | Evening window boundaries |
+| `time_night_start` / `time_night_end` | `HH:MM` | Night window boundaries |
+
+Invalid values fall back to the defaults. Configure these in the [Admin Panel](Admin-Panel.md) under Settings.
+
+See also [Teamwork Chores](Teamwork-Chores.md) — chores that need two or more children to join before they count.
diff --git a/wiki/Chore-Swaps.md b/wiki/Chore-Swaps.md
new file mode 100644
index 00000000..173262a7
--- /dev/null
+++ b/wiki/Chore-Swaps.md
@@ -0,0 +1,87 @@
+# Chore Swaps
+
+Chore swaps let a child ask to take over today's turn of a rotation chore from a sibling. The request is pending until a parent approves it, at which point the chore is reassigned to the requester for the day.
+
+
+
+---
+
+## When a Swap Is Possible
+
+Swaps only apply to **rotation chores** — those using an `alternating`, `random`, `balanced`, or `first_come` [assignment mode](Chores.md#assignment-modes), where a single child holds today's turn.
+
+A request is rejected outright if:
+
+- The chore is in `everyone` or `unassigned` mode (there is no single turn to take over)
+- The chore is already assigned to the requesting child today
+
+---
+
+## Requesting a Swap
+
+There are two ways to request a swap:
+
+- **From the child card** — see [From the Child Card](#from-the-child-card) below.
+- **With the `taskmate.request_swap` service**, or from the chore row in the [Admin Panel](Admin-Panel.md) (**Request swap** button).
+
+```yaml
+service: taskmate.request_swap
+data:
+ chore_id: b3f9a12c
+ requester_id: a8c8376a
+```
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `chore_id` | Yes | The rotation chore to take over |
+| `requester_id` | Yes | The child who wants today's turn |
+
+The service is linked-child gated — a child user can only request on their own behalf. The request is stored with a `pending` status, recording the requester, the child who currently holds the turn (`from_child_id`), and a timestamp.
+
+---
+
+## From the Child Card
+
+Since v4.0.1, a child can request a swap directly from their [child card](Dashboard-Cards.md). Below the day's chores, a **Take over a chore** section lists the rotation chores whose turn belongs to a sibling today and that this child is in the pool for. Each row shows the chore name and its (post-multiplier) points, with a **Request** button.
+
+Tapping **Request** calls `taskmate.request_swap` for that child and the button changes to **Requested** — the request then goes to the parent's approval queue. The section only lists chores in a rotation mode (`alternating`, `random`, `balanced`, `first_come`); `everyone` and unassigned chores never appear, and a child's own turn is never listed.
+
+The section is gated by the child card's **`show_swaps`** option, which is **on by default**. Set `show_swaps: false` in the card config to hide it.
+
+---
+
+## Parent Approval
+
+Pending swap requests appear to parents in the [Admin Panel](Admin-Panel.md) (with a count badge). For each, the parent can approve or reject:
+
+| Action | What happens |
+|--------|--------------|
+| **Approve** | Today's turn is reassigned to the requester — the chore's current assignee becomes the requesting child for the day, recorded as a dated override on the chore. The request itself is then consumed. |
+| **Reject** | The pending request is removed. The rotation is unchanged. |
+
+On approval, TaskMate fires a `taskmate_swap_approved` event carrying `chore_id`, `requester_id`, and `from_child_id`.
+
+Since v5.1.1 an approved request is **removed** rather than left in storage with an `approved` status. Nothing read a settled request, so those records accumulated for the life of the install; existing stores are swept clean on upgrade. The approval remains observable through the `taskmate_swap_approved` event and the chore's own dated override.
+
+> **Completing a swapped chore.** Before v5.1.1, approval wrote only the chore's cached assignee field while every eligibility gate resolved the day's assignee from pure rotation maths — so the swapped-to child saw the chore on their card but tapping it did nothing at all: no completion, no points, no pending approval, and the chore returned within 30 seconds. Approval now stamps a dated override that the resolver honours, which fixes completion along with the per-chore button, the to-do list, streak and perfect-day accounting, and calendar publishing. This was broken from v4.0.0 (when swaps were introduced) until v5.1.1.
+
+### When a Chore or Child Is Deleted
+
+Deleting a chore drops any pending swap requests for it, and deleting a child drops any request they were the requester or the previous holder of. If an approved swap pointed at the deleted child, the chore's override is cleared and the chore is repointed at today's live pool immediately.
+
+Before v5.1.1 neither delete path touched swap requests, which left the parent a permanent **"? wants to swap ?"** row in the approval queue that only rejecting could clear; and removing a child left their rotation chores pointing at a non-existent assignee, so those chores disappeared from every remaining child's card until midnight. Existing installs are swept clean on upgrade.
+
+---
+
+## Scope of a Swap
+
+A swap changes **only today's assignment** of the chore. It does not alter the underlying rotation order or anchor — the next scheduled day follows the normal rotation algorithm as if the swap had not happened.
+
+---
+
+## Related
+
+- [Chores](Chores.md) — chore configuration
+- [Chore Scheduling](Chores.md#assignment-modes) — rotation assignment modes that swaps act on
+- [Approvals-Card](Approvals-Card.md) — parent approval workflow
+- [Services](Services.md) — full `request_swap` reference
diff --git a/wiki/Chores.md b/wiki/Chores.md
new file mode 100644
index 00000000..08e6ea68
--- /dev/null
+++ b/wiki/Chores.md
@@ -0,0 +1,414 @@
+# Chores
+
+## Managing Chores
+
+
+
+Managed from the **TaskMate** panel in the Home Assistant sidebar, under **Chores**.
+
+You can add chores one at a time or in bulk (multiple chores with the same settings in one step).
+
+---
+
+## Chore Fields
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Name** | — | Display name shown on the child card |
+| **Description** | `""` | Optional subtitle shown below the name when enabled on the card |
+| **Picture** | none | Optional icon (`icon`) or **uploaded photograph** (v5.1.0+) for the chore. Classic cards show it in place of the number inside the coloured badge; Playroom, Console, Clean Pro and Accessible show it in place of the guessed emoji. Required for [Pre-Reader Mode](Pre-Reader-Mode.md). Chores without one are unchanged. *(Saved and rendered correctly since v5.0.4.)* |
+| **Points** | `10` | Stars earned when the chore is completed and approved. A parent can override this per approval — see [Open-Ended Chores](Open-Ended-Chores.md). |
+| **Difficulty** | `medium` | `easy` / `medium` / `hard` — scales the awarded points by the tier multiplier. See [Difficulty Tiers](Difficulty-Tiers.md). |
+| **Time of Day** | `anytime` | Groups the chore into a time slot — controls which child card instance shows it |
+| **Scheduling Mode** | `specific_days` | `specific_days` — appear on selected days. `recurring` — rolling recurrence window (every 2 days to every 6 months, or a custom every N days from v6.2.0). `one_shot` — single-use task, valid for one day only. See [Chore Scheduling](Chore-Scheduling.md). |
+| **Due Days** | none | Days of the week this chore is scheduled — see below |
+| **Assigned To** | all children | Which children this chore belongs to — leave empty for all |
+| **Depends On** | none | Prerequisite chores (`depends_on`); this chore stays locked until they're all approved for the child today. See [Chore Dependencies](Chore-Dependencies.md). |
+| **Requires Approval** | `true` | If on, completion is pending until a parent approves it |
+| **Require Photo Proof** | `false` | If on, completions always require parent approval; an attached evidence photo shows in approvals. See [Photo Proof](Photo-Proof.md). |
+| **Mandatory chore** | `false` | If on (`mandatory`), the chore is flagged as required and a parent can apply a penalty when it's missed. See [Mandatory Chores](Mandatory-Chores.md). |
+| **Penalty points if missed** | `0` | Points (`mandatory_penalty_points`) deducted when a parent applies the penalty for a missed mandatory chore |
+| **Expiry Date** | none | Optional ISO end date (`expires_on`); the chore auto-disables the day after this date. See [Expiry Date](#expiry-date). |
+| **Due Time** | none | Optional `HH:MM` deadline for the early-bonus / late-penalty incentive — see [Early Bonus & Late Penalty](#early-bonus--late-penalty). |
+| **Early Bonus** | `0` | Extra points added when completed at/before the due time |
+| **Late Penalty** | `0` | Points subtracted when completed after the due time |
+| **Daily Limit** | `1` | How many times per day this chore can be completed |
+| **Weekly Target** | `0` | How many times a *week* this must be done, on any of its days. `0` = off — see [Weekly Targets](Weekly-Targets.md) |
+| **Weekly Target Bonus** | `0` | *(v6.2.0)* Extra points paid once a week when the weekly target is reached. `0` = no bonus — see [Weekly Target Bonus](Weekly-Targets.md#weekly-target-bonus) |
+| **Completion Sound** | `coin` | Sound played when ticked off on the child card |
+| **Claim Allowance** | `0` min | Grace period (in minutes) after the time window ends during which the chore can still be completed |
+| **Assignment Mode** | `everyone` | How the chore is distributed among assigned children — see [Assignment Modes](#assignment-modes) below |
+| **Require Availability** | `false` | Skip children whose availability entity indicates they are unavailable |
+| **Calendar Entities** | none | HA calendar entities to publish this chore's assignments to — see [Calendar Integration](#calendar-integration) below |
+| **Task Type** | `standard` | `standard` (tick-off) or `timed` (duration-based with start/pause/stop) — see [Timed Tasks](Timed-Tasks.md) |
+| **Timed Rate Points** | `10` | Points per rate window (timed chores only) |
+| **Timed Rate Minutes** | `5` | Rate window size in minutes (timed chores only) |
+| **Daily Cap (minutes)** | `0` | Max daily duration for timed chores. `0` = unlimited |
+| **Minutes (estimate)** | `0` | *(v7.0.0)* Roughly how long it takes, 0–600. Cards add these up into "About 25 min left". `0` = not set — see [Estimated Minutes](Estimated-Minutes.md) |
+| **Reference photo** | none | *(v7.0.0)* A picture of the job done well, shown next to the child's photo when you approve — see [Reference Photos](Reference-Photos.md) |
+| **Count in (unit)** | empty | *(v7.0.0)* Makes it a quantity chore ("pages", "laps"): the child says how many and **Points** become points per unit — see [Quantity Chores](Quantity-Chores.md) |
+| **Most per go** | `0` | *(v7.0.0)* Caps how many units one completion counts. `0` = no cap, and a parent approves each one |
+| **Bonus Subtasks** | none | Optional extra-credit tasks within this chore — see [Bonus Subtasks](Bonus-Subtasks.md) |
+| **Weather conditions** | none | Hide the chore in unsuitable weather — see [Weather-Aware Chores](Weather-Aware-Chores.md) |
+| **Scheduled changes** | none | Queue a field change for a future date — see [Scheduled Config Changes](Scheduled-Config-Changes.md) |
+| **Visibility entity / operator / value** | none | Gate the chore on a Home Assistant entity — see [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) |
+
+---
+
+## Chore Pictures (v5.1.0+)
+
+The **Picture** field takes either an icon from the list or a photograph you upload. A photo of *your* dishwasher beats a generic plate outline, and for a child who can't read yet it's the difference between recognising the task and guessing.
+
+Upload a **JPEG, PNG or WebP**, up to **2 MB** per file and **64 MB** across all chores. The picture then replaces the icon everywhere the chore appears — the child card, the [routine card](Routine-Mode.md), the reorder card and the panel.
+
+**How the files are handled**
+
+- Stored locally in `taskmate_images/` beside your Home Assistant config. Nothing is uploaded anywhere.
+- Served over **signed URLs**, so a dashboard renders the picture without the viewer needing a token, while an unsigned request is refused.
+- Uploading is **admin-only**, even though chore editing is otherwise open to parents — it writes files to disk.
+- Deleted automatically when the chore goes, or when you replace the picture. Nothing sweeps the folder, so nothing is left behind.
+
+**Duplicated chores share one file.** A chore created with **Duplicate** points at the same image as its source. That is intentional and safe: the file is kept until the last chore using it is deleted or re-pictured (fixed in v5.1.0 — before that, removing either copy broke the other).
+
+---
+
+## Time of Day
+
+| Value | When to use |
+|-------|------------|
+| `morning` | Chores done before school / after waking |
+| `afternoon` | After school chores |
+| `evening` | Before dinner / homework |
+| `night` | Bedtime routine |
+| `anytime` | No time restriction — always shown |
+
+The child card can be configured to show only chores matching a specific time category. You can have multiple child cards on the same dashboard for different times of day.
+
+---
+
+## Due Days
+
+Optionally restrict a chore to specific days of the week. Valid values:
+
+`monday` `tuesday` `wednesday` `thursday` `friday` `saturday` `sunday`
+
+**Example:** A homework chore that only applies Monday–Friday.
+
+How the child card handles chores not due today is controlled by the `due_days_mode` card config:
+
+| Mode | Behaviour |
+|------|-----------|
+| `hide` | Chores not due today are hidden entirely (default) |
+| `dim` | Chores not due today are shown greyed out and non-interactive |
+| `show` | All chores shown regardless of schedule |
+
+> Due days are picked in the chore dialog's schedule section when the schedule mode is **specific days**.
+
+---
+
+## Assigned To
+
+By default, chores are assigned to **all children** — including any children you add later. To assign a chore to specific children only, select the child names during chore creation/editing.
+
+When assigned to specific children, only those children will see the chore on their child card. New children added after the chore was created will **not** automatically see it unless you edit the chore to include them.
+
+---
+
+## Requires Approval
+
+When `requires_approval` is on:
+
+1. Child taps the chore on the child card
+2. The chore shows as completed (ticked) but grayed out
+3. The child's `pending_points` balance increases
+4. The parent sees the completion in the Approvals card / Parent Dashboard
+5. **Approve** → points move from pending to the child's balance
+6. **Reject** → completion removed, no points awarded
+
+When `requires_approval` is off:
+- Points are awarded immediately on completion
+
+---
+
+## Daily Limit
+
+Controls how many times a chore can be completed in a single day. Useful for:
+- Chores that can be done multiple times (e.g. "Drink a glass of water" × 5)
+- Preventing accidental double-completions
+
+The child card shows `(0/5)` style progress when `daily_limit > 1`.
+
+A [weekly target](Weekly-Targets.md) caps this in turn: today's allowance is never more than what is left in the week, so a chore with a daily limit of 5 and one tick left in its quota offers one more, not five.
+
+---
+
+## Weekly Target
+
+Sets a weekly quota instead of leaving the chore owed every day it is scheduled: *"three times this week, any day"*. The chore stops being offered once the count is reached and resets on Monday.
+
+It sits on top of the schedule rather than replacing it, so "3× a week but weekdays only" works — choose the days as usual and add a target. Full detail on [Weekly Targets](Weekly-Targets.md).
+
+---
+
+## Difficulty Tiers
+
+Each chore has a difficulty tier — `easy`, `medium`, or `hard` — whose multiplier scales the points it awards. Medium is the neutral baseline (×1.0) and the default, so existing chores keep their exact value. With the default multipliers (easy ×0.5, medium ×1.0, hard ×2.0), a hard 10-point chore awards 20.
+
+Set difficulty in the chore dialog's **Difficulty** selector or via the `difficulty` field on `taskmate.add_chore`. The multipliers themselves are editable in Settings. On the child card, easy and hard chores carry an **Easy** / **Hard** badge; medium (the baseline) shows none.
+
+See [Difficulty Tiers](Difficulty-Tiers.md) for the full breakdown.
+
+---
+
+## Require Photo Proof
+
+When **Require Photo Proof** is on, the chore's completions **always** go through parent approval (even if Requires Approval is off), and any photo attached at completion is shown to the parent as a thumbnail in approvals. A photo is attached via the `photo_url` field on `taskmate.complete_chore` — typically a camera snapshot from an automation.
+
+See [Photo Proof](Photo-Proof.md) for the full workflow.
+
+---
+
+## Open-Ended (v5.7.0+)
+
+When **Open-ended (child describes it)** is on, tapping the chore opens a sheet asking the child what they did and how many points they think it was worth, instead of completing straight away. Like photo proof, these completions **always** go to a parent — the child is the one naming the price — and you set the real award when you approve.
+
+Use it as a single standing placeholder ("Something extra") for the helpful things that were never on the list. Leave its points at 0 and raise its daily limit.
+
+See [Open-Ended Chores](Open-Ended-Chores.md) for the full workflow.
+
+---
+
+## Estimated Minutes (v7.0.0)
+
+Give a chore a rough time in **Minutes (estimate)** and the child card shows a small `~10 mins` tag on it, plus "About 25 min left" for everything still to do today. Handy for "can I go out first?" conversations. The [Insights](Insights.md) fairness report also counts these minutes, so you can see who is putting in the time, not just the number of chores. See [Estimated Minutes](Estimated-Minutes.md).
+
+---
+
+## Reference Photo (v7.0.0)
+
+Upload a **Reference photo** of what the job looks like done well (a made bed, a clear table). When the child sends a photo as [proof](Photo-Proof.md), the approval shows the two side by side, so it's easy to compare. Uploaded and stored like a [chore picture](#chore-pictures-v510). See [Reference Photos](Reference-Photos.md).
+
+---
+
+## Quantity Chores (v7.0.0)
+
+For "read 20 pages" or "swim 10 lengths", type the unit in **Count in (unit)**. Tapping the chore then asks the child "How many pages?" and shows what that's worth; **Points** are paid per unit, with the difficulty multiplier on top. **Most per go** caps one completion. A chore with no cap always goes to a parent for approval, because the child picked the number. Quantity chores can't be finished from the kiosk, the chore board, the sticker chart or by voice, since those can't ask how many. See [Quantity Chores](Quantity-Chores.md).
+
+---
+
+## Mandatory Chores
+
+Turn on the **Mandatory chore** toggle (`mandatory`) to mark a chore as required. A **Penalty points if missed** field (`mandatory_penalty_points`) then sets the points a parent may deduct when the chore is missed. When a mandatory chore isn't completed in time, TaskMate raises a review item for the parent rather than auto-deducting — the parent chooses whether to apply the penalty.
+
+See [Mandatory Chores](Mandatory-Chores.md) for the full workflow.
+
+---
+
+## Expiry Date
+
+Any chore can carry an optional expiry date (`expires_on`, an ISO date). The chore stays active **through** the expiry date and is automatically soft-disabled the day after it passes — the midnight maintenance step disables any enabled chore whose `expires_on` is before today.
+
+- Expiry is **inclusive on the day** — a chore with `expires_on` of `2026-07-01` is still available on 1 July and disables on 2 July.
+- Soft-disable means the chore is set `enabled = false` (kept in storage for history), exactly like one-shot expiry. Leave the field blank for no expiry.
+- Set it via the **Expiry date** picker in the chore dialog.
+
+---
+
+## Early Bonus & Late Penalty
+
+A chore can reward promptness with a time-of-day incentive. Set an optional **Due Time** (`HH:MM`); a completion timestamped **at or before** that time earns the **Early Bonus** added to its award, and one **after** it loses the **Late Penalty**.
+
+- Both adjustments are applied to the award value *after* the difficulty multiplier, on both completion and approval.
+- The penalty never drops the award below zero.
+- Leave **Due Time** blank to disable the incentive entirely (early bonus / late penalty are ignored).
+- Timed chores earn by rate window, so the incentive applies the same way to their computed award.
+
+**Example:** A "Make bed" chore worth 10 points with a due time of `08:00`, early bonus `5`, late penalty `3` — awards 15 if done by 08:00, or 7 if done later.
+
+---
+
+## Completing on Behalf of a Child
+
+A parent can complete a chore *for* a child using the `as_parent` flag on `taskmate.complete_chore`. This **auto-approves** the completion and awards points immediately, bypassing approval — even for approval-required or photo-required chores.
+
+```yaml
+service: taskmate.complete_chore
+data:
+ chore_id: b3f9a12c
+ child_id: a8c8376a
+ as_parent: true
+```
+
+This is an admin-only action. The `as_parent` path is gated on the backend (not just hidden in the UI): user-initiated service calls must come from an admin user, and the panel/cards expose the control only to admins. Calls without a user context (automations, scripts, schedules) pass through. Normal child self-completion (with `as_parent` omitted) is unaffected.
+
+The control is also available from the Overview tab of the [Admin Panel](Admin-Panel.md) / Parent Dashboard.
+
+---
+
+## Vacation / Pause Mode
+
+You can mark date ranges as time off. During a vacation, **all chores are paused** and **streaks are frozen** — vacation days never count as missed, so a streak survives a holiday. Vacations are global (all children) and configured in Settings.
+
+See [Vacation Mode](Vacation-Mode.md) for the full feature.
+
+---
+
+## Sibling Swaps
+
+A child can ask to take over today's turn of a rotation chore from a sibling — from their child card or via a service call — subject to parent approval. On approval, today's assignment is reassigned to the requester; the underlying rotation is unchanged. Any rotation chore can be swapped (`alternating` / `random` / `balanced` / `first_come`) — not `everyone` or unassigned chores.
+
+See [Chore Swaps](Chore-Swaps.md) for the full workflow.
+
+---
+
+## Cloning a Chore
+
+Use the **Duplicate** button on a chore row in the [Admin Panel](Admin-Panel.md) to copy a chore's full configuration into a new one. The clone:
+
+- Gets a fresh chore ID and a name suffixed with **(copy)**
+- Copies all settings, including bonus subtasks (which get fresh subtask IDs)
+- Starts with **clean runtime state** — nothing disabled-for, enabled, no skip/assignment/calendar-publish carry-over
+- For one-shot chores, gets today's date as its new `created_date`
+
+The source chore is left untouched. Cloning is admin-only and is recorded in the [Admin Audit Log](Admin-Audit-Log.md).
+
+---
+
+## Bulk Operations
+
+From the [Admin Panel](Admin-Panel.md) Chores tab, use **Select** mode to tick multiple chores and act on them at once via the action bar:
+
+| Action | Effect |
+|--------|--------|
+| **Delete** | Permanently removes the selected chores |
+| **Enable** | Re-enables them and clears any per-child disabled state |
+| **Disable** | Soft-disables them (kept in storage) |
+| **Reassign to…** | Sets the **Assigned To** list of all selected chores to the chosen children |
+
+Bulk actions are admin-only. Deleting asks for confirmation first.
+
+---
+
+## Assignment Modes
+
+Controls how a chore is distributed when assigned to multiple children.
+
+| Mode | Behaviour |
+|------|-----------|
+| `everyone` | All assigned children see the chore every day (default) |
+| `alternating` | Round-robin through assigned children, one child per day. Uses the rotation anchor date to determine whose turn it is. |
+| `random` | Deterministic per-day random pick from the assigned pool. Stable within a day — refreshing won't change the pick. Each chore rolls independently. |
+| `balanced` | Splits today's balanced-mode chores evenly across the pool so no single child gets swamped. |
+| `first_come` | Competitive — the chore is shown to the whole pool and the first child to complete it wins; it then locks for everyone else for the day. See [First Come First Served](Chore-Scheduling.md#first-come-first-served). |
+| `unassigned` | Not auto-assigned to any child. The chore is hidden from child cards — a parent must complete it on behalf of a child via a service call or the admin panel. Use for parent-only or optional tasks. |
+
+For `alternating` and `random` modes, an **Assignment Rotation Anchor** date is used as the starting reference point for the rotation/randomisation algorithm.
+
+> **Note:** When a child's availability entity is unavailable and **Require Availability** is on, they are skipped in the rotation.
+
+### Manual Start Override
+
+Use `taskmate.set_chore_manual_start` to force the rotation to start with a specific child:
+
+- **Alternating mode:** Reorders the rotation so the chosen child is first and resets the anchor to today
+- **Random/Balanced modes:** Overrides today's assignment only — the deterministic algorithm takes over tomorrow
+
+### Skip Today's Child
+
+Use `taskmate.skip_chore` to skip today's assigned child and move to the next in the rotation:
+
+- Only works for non-`everyone` modes with a pool of 2+ children
+- The skip is ephemeral — it applies only today and resets at midnight
+- Maximum skips per day = pool size − 1
+
+### Task Groups
+
+Related rotation chores can be coordinated using [Task Groups](Task-Groups.md) with sticky (same child) or spread (different children) policies.
+
+### Real-time reassignment
+
+For chores using `alternating`, `random`, or `balanced` modes with **Require Availability** enabled, TaskMate monitors the availability entity in real time. When a child's availability state changes (e.g. they leave the house and a presence sensor flips to `off`), TaskMate automatically reassigns the chore to the next available child in the pool.
+
+- Reassignment only applies to chores that have **not** already been completed today — a chore a child has already ticked off will not move
+- In `everyone` mode, availability is resolved at display time instead — unavailable children simply don't see the chore on their card
+- Reassignment happens silently with no notification. The chore will appear on the newly assigned child's dashboard on next refresh (within 30 seconds)
+
+**Recognised "available" states:** `on`, `home`, `available`, `present`, `true`. Any other state is treated as unavailable.
+
+---
+
+## Claim Allowance
+
+The claim allowance is a grace period (in minutes) after the chore's time window ends. For example, if a chore is set to `morning` and the claim allowance is `15`, the child has 15 extra minutes past the morning window to complete it.
+
+Default: `0` (no grace period).
+
+> **Note:** This field is stored in the chore configuration but is not yet enforced by the backend. It is reserved for a future update.
+
+---
+
+## Calendar Integration
+
+Chores can be published to one or more Home Assistant calendar entities. When configured:
+
+- All-day events are created for each assigned child on their scheduled days
+- Events are projected ahead by the configured number of days (default: **14 days**, configurable 1–90 in Settings)
+- Calendar entries are idempotent — duplicates are prevented automatically
+- Old entries are cleaned up before each projection
+
+To configure: select one or more calendar entities in the chore's **Calendar Entities** field. Set the projection horizon in **Settings → Calendar Projection Days**.
+
+---
+
+## Completion Sound
+
+Each chore can have its own sound that plays when it's ticked off on the child card. This overrides the card's `default_sound` setting.
+
+Available sounds: `none`, `coin`, `levelup`, `fanfare`, `chime`, `powerup`, `undo`, `fart1`–`fart10`, `fart_random`
+
+See [Completion Sounds](Dashboard-Cards.md#completion-sounds) for descriptions of each sound.
+
+---
+
+## Bulk Adding Chores
+
+Use **Bulk add** to create several chores at once with the same settings. Enter chore names one per line or comma-separated:
+
+```
+Make Bed
+Brush Teeth
+Tidy Bedroom
+Put Shoes Away
+```
+
+All created chores will share the same points, time of day, assignment, and other settings. You can edit them individually afterwards.
+
+> **Note:** Bulk add does not support **Assignment Mode**, **Rotation Anchor**, **Require Availability**, or **Calendar Entities**. These must be configured individually after creation by editing each chore.
+
+---
+
+## Chore IDs
+
+Each chore has an auto-generated 8-character ID (e.g. `b3f9a12c`). This ID is used in:
+- Service calls (`taskmate.complete_chore`)
+- The `assigned_to` field in child records
+- Chore order lists
+
+To find a chore's ID: Developer Tools → States → `sensor.taskmate_overview` → expand attributes → look in the `chores` array.
+---
+
+## Related
+
+- [Chore Scheduling](Chore-Scheduling.md) — specific days, recurring, one-shot, rotation and first-come modes
+- [Chore Dependencies](Chore-Dependencies.md) — lock a chore until its prerequisites are approved
+- [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) — gate a chore on a Home Assistant entity state
+- [Weather-Aware Chores](Weather-Aware-Chores.md) — hide outdoor chores when the weather is unsuitable
+- [Reactive Chores](Reactive-Chores.md) — automation-raised chores with a deadline and a speed bonus
+- [Scheduled Config Changes](Scheduled-Config-Changes.md) — queue an edit to take effect on a future date
+- [Chore Roulette](Chore-Roulette.md) — spin for a random outstanding chore with a multiplier
+- [Chore Auctions](Chore-Auctions.md) — let children bid the fewest points they'd do an unpopular chore for
+- [Bounty Board](Bounty-Board.md) — one-off jobs at a fixed price, first to claim
+- [NFC / QR Tag Completion](NFC-Tag-Completion.md) — complete a chore by scanning a tag with the companion app
+- [Insights](Insights.md) — the friction report, for chores that never get done
+- [Estimated Minutes](Estimated-Minutes.md), [Reference Photos](Reference-Photos.md), [Quantity Chores](Quantity-Chores.md), [Auto-Approve](Auto-Approve.md), [Sick Days](Sick-Days.md) — v7.0.0 chore features
+- [Services](Services.md) — the full service reference
diff --git a/wiki/Completion-Sounds.md b/wiki/Completion-Sounds.md
new file mode 100644
index 00000000..7ab71ce2
--- /dev/null
+++ b/wiki/Completion-Sounds.md
@@ -0,0 +1,66 @@
+# Completion Sounds
+
+Ticking off a chore plays a sound. TaskMate ships a set of built-in effects, and from v5.6.0 you can upload your own clips and choose one per chore — a recorded "well done", a favourite game noise, whatever gets a five-year-old to do the bins.
+
+
+
+---
+
+## Built-In Sounds
+
+Every chore has a **Completion sound** in its editor. Six of the built-ins — coin, level-up, fanfare, chime, power-up and undo — are synthesised in the browser, so they involve no files at all. The joke sounds are short clips shipped with the integration. `none` plays nothing. None of them need an upload.
+
+---
+
+## Uploading Your Own
+
+**Admin panel → Settings → Completion sounds → Upload sound.**
+
+| | |
+|---|---|
+| Formats | MP3, OGG, WAV, M4A |
+| Maximum size | 1 MB per clip |
+
+The format list is deliberately short: these are the ones every browser Home Assistant runs in can decode. A clip that stored fine but silently failed to play would be worse than a refused upload.
+
+The 1 MB cap is about purpose rather than disk space. A completion sound is instant feedback on a tap — anything approaching a song would delay the very thing it is meant to reward.
+
+Once uploaded, a sound can be **played**, **renamed** or **deleted** from the same screen.
+
+---
+
+## Using One On A Chore
+
+Open any chore and pick your sound from **Completion sound**. Uploaded sounds appear in the same dropdown as the built-ins, under the name you gave them.
+
+---
+
+## Key Points
+
+- **Uploads are admin-only.** Children can play sounds, not add them.
+- **The file type is checked by reading the file, not by trusting its name.** Renaming a document to `.mp3` will not get it in.
+- **Deleting a sound resets the chores using it.** Any chore pointing at a deleted sound goes back to the default rather than falling silent, and the panel tells you how many were changed.
+- **Sounds are configuration, not history.** Unlike chore evidence photos they are never swept automatically; they stay until you delete them.
+- **Browsers block audio until the page has been interacted with.** The first sound after a fresh page load may not play; any tap on the dashboard is enough to release it.
+
+---
+
+## Previewing From A Script
+
+The `taskmate.preview_sound` service plays a sound in open dashboards, which is handy when picking one:
+
+```yaml
+action: taskmate.preview_sound
+data:
+ sound: fanfare
+```
+
+An uploaded sound is referenced by its stored value, which the panel shows for you; built-ins use their plain name.
+
+---
+
+## See Also
+
+- [Celebrations](Celebrations.md) — the bigger moments: level-ups, streak milestones, perfect weeks
+- [Dashboard Cards](Dashboard-Cards.md) — which cards play completion sounds
+- [Admin Panel](Admin-Panel.md) — where the Settings screens live
diff --git a/wiki/Configuration-Entities.md b/wiki/Configuration-Entities.md
new file mode 100644
index 00000000..d70ac04b
--- /dev/null
+++ b/wiki/Configuration-Entities.md
@@ -0,0 +1,72 @@
+# Configuration Entities
+
+A handful of TaskMate's most useful settings are also exposed as standard Home Assistant **number** and **select** entities. This lets you read or change them straight from the HA UI, or from an automation or script, without going through the [Admin Panel](Admin-Panel.md) or a service call.
+
+
+
+These entities and the Admin Panel are two views of the **same** stored settings — change one and the other updates to match.
+
+---
+
+## Number Entities
+
+| Entity | Friendly name | Range | Step | Default | Controls |
+|--------|---------------|-------|------|---------|----------|
+| `number.taskmate_weekend_multiplier` | Weekend multiplier | 1.0–5.0 | 0.5 | 2.0 | Multiplier applied to chore points on Saturday and Sunday. Set `1.0` to disable. See [Bonus Points](Bonus-Points.md). |
+| `number.taskmate_perfect_week_bonus` | Perfect week bonus | 0–1000 | 1 | 50 | Points awarded to a child who completes at least one chore every day Mon–Sun. See [Bonus Points](Bonus-Points.md). |
+
+---
+
+## Select Entities
+
+| Entity | Friendly name | Options | Default | Controls |
+|--------|---------------|---------|---------|----------|
+| `select.taskmate_streak_reset_mode` | Streak reset mode | `reset`, `pause` | `reset` | What happens when a child misses a day. **reset**: the streak goes back to 0. **pause**: the streak freezes and resumes on the next completion. |
+| `select.taskmate_card_design` | Card design | `classic`, `playroom`, `console`, `cleanpro`, `accessible` | `classic` | The global default visual style for TaskMate cards. See [Card Design Styles](Card-Design-Styles.md). |
+
+The entity IDs above use each setting's translation key. If you've renamed entities in Home Assistant, your IDs may differ — look them up under **Settings → Devices & services → Entities** and filter by the **TaskMate** device.
+
+---
+
+## Changing Them
+
+### From the UI
+
+Add the entities to a dashboard (for example with an Entities card) and adjust them directly — slide the number, or pick from the dropdown. Changes save immediately and are reflected in the Admin Panel settings.
+
+### From an automation
+
+Because they're ordinary entities, you can drive them from automations. For example, raise the weekend multiplier during a school-holiday week:
+
+```yaml
+alias: TaskMate — Holiday week double points
+triggers:
+ - trigger: state
+ entity_id: calendar.school_holidays
+ to: "on"
+actions:
+ - action: number.set_value
+ target:
+ entity_id: number.taskmate_weekend_multiplier
+ data:
+ value: 2.0
+```
+
+Or switch every card to the playroom style for younger users:
+
+```yaml
+actions:
+ - action: select.select_option
+ target:
+ entity_id: select.taskmate_card_design
+ data:
+ option: playroom
+```
+
+---
+
+## See Also
+
+- [Settings](Settings.md) — the full settings reference (these entities mirror a subset of it)
+- [Bonus Points](Bonus-Points.md) — weekend multiplier and perfect-week bonus in detail
+- [Card Design Styles](Card-Design-Styles.md) — the available card styles
diff --git a/wiki/Dashboard-Cards.md b/wiki/Dashboard-Cards.md
new file mode 100644
index 00000000..251dcedb
--- /dev/null
+++ b/wiki/Dashboard-Cards.md
@@ -0,0 +1,1033 @@
+# Dashboard Cards
+
+TaskMate includes 30 Lovelace cards. They are automatically registered as resources when the integration loads.
+
+All cards support a `header_color` config option — a hex colour for the card header background. Each card has its own vibrant default.
+
+---
+
+## Card design
+
+Every card accepts an optional `card_design` config key — `classic` / `playroom` / `console` / `cleanpro` / `accessible` / `global` — and exposes a **Card design** dropdown in its GUI editor. Leave it on *Use global default* (or omit the key) to follow the dashboard-wide default; set it to any single style to skin that one card. See [Card Design Styles](Card-Design-Styles.md).
+
+```yaml
+card_design: playroom # classic | playroom | console | cleanpro | accessible | global
+```
+
+---
+
+## Which Cards Do I Need?
+
+For a first-time setup, you only need **three cards**:
+
+| Card | Who sees it | Purpose |
+|------|-------------|---------|
+| **Child Card** | Kids | Complete chores, hear sounds, see celebrations |
+| **Rewards Card** | Kids | Browse and claim rewards |
+| **Parent Dashboard Card** | Parents | Approve chores, manage points, see overview |
+
+Everything else is optional and can be added later as you explore:
+
+| Card | Best for |
+|------|----------|
+| Routine Card | Walking a young child through a morning or bedtime sequence, one task at a time |
+| Badges Card | Showing earned and locked achievement badges with tier filtering |
+| Approvals Card | Dedicated approval screen (instead of the tab in Parent Dashboard) |
+| Points Card | Quick +/- point adjustments with custom amounts |
+| Penalties / Bonuses Cards | Reusable named deductions and awards |
+| Streak Card | Motivating kids with streak history and badges |
+| Leaderboard Card | Competitive households with multiple children |
+| Weekly Card | Reviewing the week's activity |
+| Points Graph Card | Tracking points trends over time |
+| Points Display Card | Wall-mounted tablet showing points |
+| Reward Progress Card | Wall-mounted tablet showing progress toward a single reward |
+| Calendar Card | Day-by-day view of chore assignments |
+| Overview Card | At-a-glance summary for parents |
+| Reorder Card | Customising chore display order per child |
+| Family Goal Card | Tracking progress toward a shared co-op family goal |
+| Photo Gallery Card | Browsing submitted chore-proof photos |
+| Kiosk Card | A shared wall tablet where each child taps their face to see their own chores |
+| Bounty Card | Letting a child claim and finish one-off jobs from the bounty board |
+| Wishlist Card | Letting a child save towards things they want |
+| Recap Card | A "Wrapped"-style story of a child's week, month or year |
+| Auction Card | Letting a child bid on auctioned chores |
+| Sticker Chart Card | A young child's whole day as stickers to tap, with stars filling towards a reward |
+| Pet Card | A virtual pet that hatches and grows as the child does chores |
+| Raffle Card | Children buy raffle tickets with points, and watch the draw |
+
+---
+
+## Adding Cards
+
+1. Edit your dashboard → **+ Add Card**
+2. Search "taskmate" or scroll to Custom
+3. Select a card and configure via the visual editor, or use YAML
+
+All cards default to `entity: sensor.taskmate_overview` — leave it as-is unless you have renamed the entity.
+
+### Shared kids' dashboards: `show_parent_actions` (v6.2.0)
+
+On a tablet or shared screen the children use, a parent account often stays signed in. Normally the cards then offer that parent's controls to whoever taps them, so a child could, say, undo a finished chore long after their own [undo window](Child-Undo-Window.md) has closed.
+
+Set `show_parent_actions: false` on a card and it behaves exactly as it would for a child, whoever is signed in. It defaults to `true`, and the switch is also in each card's visual editor as **Show parent actions**.
+
+| Card | With `show_parent_actions: false` |
+|------|-----------------------------------|
+| [Child](#child-card) | Tapping a done chore (or a done bonus sub-task) uses the child's own undo window. Outside it, the card says "Only a parent can undo a completed chore." |
+| [Chore Board](#chore-board-card) | The same: **Undo** follows the child's undo window |
+| [Overview](#overview-card) | Child tiles don't expand to offer completing chores on the child's behalf |
+| [Bonuses](#bonuses-card) / [Penalties](#penalties-card) | No Apply buttons and no edit or manage controls |
+
+```yaml
+type: custom:taskmate-child-card
+child_id: a8c8376a
+show_parent_actions: false
+```
+
+This only changes what the card shows. Every action still goes through TaskMate's normal permission checks. The Approvals, Points and Parent Dashboard cards are for parents only, so they have no such option; leave them off a kids' dashboard. The Activity card has its own `show_undo` option.
+
+### Adult profiles: `show_adults` (v6.4.0)
+
+Cards that list the whole family leave [adult profiles](Adult-Profiles.md) out by default. Set `show_adults: true` to include them, listed after the children. The **Show adults** switch appears in the card editor once your family has an adult profile (on the Chore Board, set it in YAML).
+
+```yaml
+type: custom:taskmate-leaderboard-card
+entity: sensor.taskmate_overview
+show_adults: true
+```
+
+It applies to the Leaderboard, Overview, Points, Points Display, Points Graph, Streak, Weekly, Calendar, Sticker Chart, Reward Progress, Parent Dashboard, Kiosk, Chore Board, Rewards, Bonuses, Penalties and Bounty cards. A card set to one `child_id` always shows that profile, adult or not. See [Adult Profiles](Adult-Profiles.md#which-cards) for what each card leaves out.
+
+### Child photos (v6.4.0)
+
+When a child has a [photo](Children.md#child-photos), every card shows it in place of their avatar icon. There is nothing to configure on the card.
+
+---
+
+## Child Card
+
+
+
+**Purpose:** The primary card for kids — displays their chores with big colourful buttons, completion sounds, and celebrations.
+
+**Default header colour:** Purple `#9b59b6`
+
+```yaml
+type: custom:taskmate-child-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # required
+time_category: anytime # current | morning | afternoon | evening | night | anytime | all
+include_anytime_chores: true # false hides Anytime chores from every time_category
+due_days_mode: hide # hide | dim | show — for specific-day chores not due today
+recurrence_done_mode: dim # dim | hide | show — for recurring chores already completed
+dependency_mode: hide # hide | dim | show — chores waiting on another to be approved
+first_come_claimed_mode: hide # hide | dim | show — first-come chores claimed by another child
+show_countdown: true # show midnight reset countdown
+show_minutes_left: true # (v7.0.0) "About 25 min left" from the chores' estimated minutes
+show_help_button: true # (v7.0.0) the "I'm stuck" button on each outstanding chore
+show_mood: true # (v7.0.0) end-of-day mood check-in once the day's chores are done
+show_weekly_goal: true # (v7.0.0) the child's own weekly goal (needs the global setting)
+elapsed_time_mode: dim # dim | hide | show — time-of-day chores whose window has passed
+show_description: false # show chore description below name
+show_badges: true # show earned badge strip below points
+show_next_badge: true # show progress toward the closest unearned badge
+show_due_days_only: false # only show chores due today (ignore time_category filter)
+show_swaps: true # show the "Take over a chore" swap section
+show_roulette: false # show the chore-roulette spin button (also needs the global setting)
+pre_reader: false # picture-only mode for children who can't read yet
+pre_reader_labels: false # in pre-reader mode, put the chore name back under each tile
+pre_reader_points: false # in pre-reader mode, show the point value instead of stars
+default_sound: coin # default completion sound
+undo_sound: undo # sound when undoing
+show_parent_actions: true # (v6.2.0) false = act as the child even when a parent is signed in
+header_color: "#9b59b6"
+```
+
+**Behaviour:**
+- Tap a chore row to complete it (the whole row is a button — no small target)
+- Tap a completed chore to undo it
+- Chores requiring approval show as ticked but pending until approved
+- If `daily_limit > 1`, a counter `(0/3)` appears beside the points
+- When all chores are done, an animated "All Done!" state is shown
+- A confetti and celebration popup appears on completion
+- **Timed tasks** show Start/Pause/Stop buttons with a live elapsed timer instead of a checkbox — see [Timed Tasks](Timed-Tasks.md)
+- **Bonus subtasks** appear as completable items below the parent chore after it's ticked off — see [Bonus Subtasks](Bonus-Subtasks.md)
+- **Badge strip** shows up to 5 most-recently-earned badges below the points readout — tap to open the admin panel's badges section. Disable with `show_badges: false`. See [Achievement Badges](Achievement-Badges.md)
+- **Next badge progress (v5.1.1+)** — a compact **Next up** line under the badge strip showing the closest unearned badge: tier-coloured icon, badge name, a thin bar and a `845 / 1000` count. Hidden when there is nothing left to earn or every remaining badge is still at 0%. Tap it to open the badges section. Disable with `show_next_badge: false`. See [Achievement Badges](Achievement-Badges.md)
+- **Level badge + XP bar** — when the child has a level, a `Lvl N` pill and a thin XP progress bar appear under the child's name in the header, filling toward the next level. The progress is driven by the child's `level`, `level_progress`, and `level_target` values. Nothing to configure — it appears automatically once levels are active. See [Levels and XP](Levels-and-XP.md)
+- **Avatar picker** — tap the child's avatar to open a picker of available avatars. Locked avatars are greyed out and show their unlock requirement on hover; tapping an unlocked one calls `taskmate.choose_avatar` to switch. See [Avatars](Avatars.md)
+- **`elapsed_time_mode`** controls morning/afternoon/evening/night chores once their time window has passed: `dim` (default) greys them out, `hide` removes them, `show` leaves them active. Chores set to `Anytime` are never affected. Already-completed chores still show their green done style regardless
+- **`time_category: current` (v5.5.0+)** shows only the chores for whichever period is active at that moment, and re-titles the card to match ("Afternoon Chores"). Unlike a fixed period, **future chores are not shown at all** — no dimmed previews — which is what makes it suitable for a wall dashboard or kiosk where upcoming work would confuse a child. It follows your own [custom time periods](Settings.md#custom-time-of-day-periods-v400), not just the built-in four, so a `School run` period works the same way. Chores still inside their post-period claim grace stay tappable, and past periods are governed by `elapsed_time_mode` as usual
+- **`include_anytime_chores` (v5.5.0+)** — Anytime chores normally appear under *every* `time_category`. Set this to `false` to hide them, leaving only the chores belonging to the selected period. Defaults to `true`, so existing cards are unaffected. Pairs well with `time_category: current` for a strict "what's due right now" view
+- **Difficulty badge** — each chore shows a small badge for its difficulty tier (easy / medium / hard). See [Difficulty Tiers](Difficulty-Tiers.md)
+- **Mandatory badge** — chores marked mandatory show a **⚠ Mandatory** badge
+- **Take over a chore** — an optional swap section lets a child take over a chore assigned to someone else. Controlled by `show_swaps` (default on). See [Chore Swaps](Chore-Swaps.md)
+- **Chore roulette** — an optional spin button that picks a random outstanding chore for a multiplier. Needs both `show_roulette: true` here **and** the global roulette setting. See [Chore Roulette](Chore-Roulette.md)
+- **Pre-reader mode** — `pre_reader: true` replaces names and numbers with a big picture and a row of stars, for children who can't read yet. `pre_reader_labels: true` puts the names back underneath. See [Pre-Reader Mode](Pre-Reader-Mode.md)
+- **Teamwork chores (v6.0.0)** — a [teamwork chore](Teamwork-Chores.md) shows "2 / 3 joined" with the joined children's avatars and a **Join** / **Leave** button instead of a plain tick
+- **Birthday banner (v6.0.0)** — on the child's [birthday](Birthday-Mode.md) the card shows a birthday banner with confetti
+- **Streak freezes (v6.0.0)** — the child's ❄️ token count shows on the card while [streak freezes](Streak-Freezes.md) are on
+- **Sent back (v6.0.0)** — a chore or reward claim rejected with a [reason](Reject-Reasons.md) shows "Sent back: …" for 24 hours, or until the child tries again
+- **Inspections (v6.0.0)** — an "Inspection coming" banner (unless it's a secret check), then the result, for [surprise inspections](Surprise-Inspections.md). A pass plays a celebration
+- **Child undo (v6.0.0)** — with the [child undo window](Child-Undo-Window.md) on, a child can take back a chore they just did, without a parent
+- **Auction wins (v6.0.0)** — a chore won at [auction](Chore-Auctions.md) shows only on the winner's card that day, at the winning price
+- **Minutes left (v7.0.0)** — chores with [estimated minutes](Estimated-Minutes.md) show a `~10 mins` tag, and the card adds up what's still to do into "About 25 min left" beside the countdown. Hide the total with `show_minutes_left: false`
+- **I'm stuck (v7.0.0)** — each outstanding chore has an "I'm stuck" button that asks a parent for help without completing or skipping anything; the chore then shows "Help is on its way". Hidden with `show_help_button: false`, and always hidden in pre-reader mode. See [Help Requests](Help-Requests.md)
+- **Mood check-in (v7.0.0)** — once the day's chores are done, the card asks "How was your day?" with five faces. One answer per day. Hide it with `show_mood: false`. See [Mood Check-In](Mood-Check-In.md)
+- **Weekly goal (v7.0.0)** — while weekly goals are on in Settings, the child sets their own points target for the week and sees a progress bar towards it. Hide it with `show_weekly_goal: false`. See [Weekly Goals](Weekly-Goals.md)
+- **Sick day (v7.0.0)** — on a [sick day](Sick-Days.md) the card says "Rest up and get better" and shows no chores due; anything already ticked stays listed so it can still be undone
+- **Make it right (v7.0.0)** — after a penalty with a [make-it-right](Make-It-Right-Penalties.md) chore, the card says which chore to do and by when to earn points back, and that chore appears on the list even if it isn't normally due
+- **Quantity chores (v7.0.0)** — tapping a [quantity chore](Quantity-Chores.md) asks "How many pages?" with − / + buttons and shows what it's worth before it is sent
+- **`first_come_claimed_mode` (v5.4.0+)** controls what the rest of the pool sees once a [first-come](Chore-Scheduling.md#first-come-first-served) chore has been claimed: `hide` (default — the row disappears for everyone, matching pre-5.4.0 behaviour), `dim` (greyed out) or `show` (full opacity). Under `dim` and `show` the winner keeps their normal completed row with undo, and every other child gets a locked row reading *"Already done by {name}"*. Not tappable in either case
+
+**`time_category` values:**
+
+| Value | Shows |
+|-------|-------|
+| `current` | **(v5.5.0+)** Chores in whichever period is active right now, plus anytime |
+| `morning` | Chores with time_category = morning or anytime |
+| `afternoon` | Chores with time_category = afternoon or anytime |
+| `evening` | Chores with time_category = evening or anytime |
+| `night` | Chores with time_category = night or anytime |
+| `anytime` | Chores with time_category = anytime only |
+| `all` | All chores regardless of time_category |
+
+**`due_days_mode` values** (Mode A — Specific Days chores):
+
+| Value | Behaviour |
+|-------|-----------|
+| `hide` | Chores not due today are hidden |
+| `dim` | Chores not due today shown greyed out, non-interactive |
+| `show` | All chores shown regardless of schedule |
+
+**`first_come_claimed_mode` values** (first-come chores already claimed by someone):
+
+| Value | Behaviour |
+|-------|-----------|
+| `hide` | **Default.** The row is removed from every card in the pool once claimed |
+| `dim` | The row stays, greyed out and not tappable, labelled with who claimed it |
+| `show` | The row stays at full opacity, still not tappable, labelled with who claimed it |
+
+A pool-wide dismissal from the admin panel has no specific winner, so every child sees *"Already claimed today"* instead of a name. Honoured by the standard chore row and all six [design styles](Card-Design-Styles.md) — but **not** by timed-task cards or pre-reader tiles, which stay live and tappable regardless (the same gap applies to `recurrence_done_mode`).
+
+---
+
+## Routine Card
+
+
+
+**Purpose:** A guided, one-task-at-a-time flow for morning and bedtime routines — a single task with a big **Done** button, a progress bar and a celebration at the end. See [Routine Mode](Routine-Mode.md).
+
+**Default header colour:** Purple `#7c3aed`
+
+```yaml
+type: custom:taskmate-routine-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # required
+time_category: morning # morning | afternoon | evening | night | anytime | all
+title: Morning routine # optional
+card_design: global # optional
+```
+
+| Control | Effect |
+|---------|--------|
+| **Done** | Completes the chore and moves to the next one |
+| **Skip for now** | Moves on without completing — the task stays outstanding |
+| **Back** | Returns to the previous task, so a mis-tap is recoverable |
+
+**`time_category` is exact** — a `morning` routine shows only morning chores, not `anytime` ones. Use `all` for everything.
+
+---
+
+## Rewards Card
+
+
+
+**Purpose:** Shows available rewards with progress bars. Children can claim rewards from this card.
+
+**Default header colour:** Orange `#e67e22`
+
+```yaml
+type: custom:taskmate-rewards-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+show_child_badges: true # show assigned children on each reward
+enable_pool_mode: false # force all rewards on this card into pool/savings-jar mode
+deposit_amounts: [1, 5, 10] # quick-deposit button amounts for pool/jackpot rewards
+header_color: "#e67e22"
+```
+
+**Behaviour:**
+- Progress bar shows current points vs reward cost
+- Jackpot rewards show a colour-coded multi-segment bar with each child's contribution
+- Claim button appears when the child can afford the reward
+- After claiming: shows "Awaiting parent approval" until approved
+- If no `child_id` set, a **Viewing as** dropdown appears below the header — select a child to activate claim buttons for them
+- **Pool / jackpot rewards** show quick-deposit buttons (set by `deposit_amounts`, default `[1, 5, 10]`) plus an **Amount** field for any custom value — see [Pool Mode](Pool-Mode-(Savings-Jars).md)
+
+---
+
+## Approvals Card
+
+
+
+**Purpose:** Review and approve or reject pending chore completions.
+
+**Default header colour:** Green `#27ae60`
+
+```yaml
+type: custom:taskmate-approvals-card
+entity: sensor.taskmate_overview
+title: Pending Approvals
+child_id: a8c8376a # optional — filter to one child
+header_color: "#27ae60"
+```
+
+**Behaviour:**
+- Items grouped by date (Today / Yesterday / date) and time of day
+- ✗ button on the left to reject, ✓ button on the right to approve
+- Pulsing red badge in header shows count when items are pending
+- Evidence-photo thumbnails render inline for completions that include a proof photo — see [Photo Proof](Photo-Proof.md)
+- **Star ratings (v6.0.0)** — with [quality ratings](Quality-Ratings.md) on, approving shows a ★ / ★★ / ★★★ picker that scales the points
+- **Reject with a reason (v6.0.0)** — rejecting a chore or reward claim offers a reason box with quick chips ("Not finished", "Needs redoing", "Not today"). See [Reject Reasons](Reject-Reasons.md)
+- **Bounties and wishes (v6.0.0)** — finished [bounties](Bounty-Board.md) and [wish](Wishlist.md) redemptions appear alongside chores and reward claims
+
+---
+
+## Points Card
+
+
+
+**Purpose:** Manually add or remove points from a child.
+
+**Default header colour:** Blue `#2980b9`
+
+```yaml
+type: custom:taskmate-points-card
+entity: sensor.taskmate_overview
+title: Manage Points
+quick_add_amounts: [1, 5, 10] # configurable add buttons
+quick_remove_amounts: [1, 5, 10] # configurable remove buttons
+show_dialog: true # show ⋯ button for custom amount + reason
+header_color: "#2980b9"
+```
+
+**Behaviour:**
+- Each child shows two rows of quick-tap buttons — add row and remove row
+- Tapping a button applies immediately with no confirmation dialog
+- The `⋯` button at the end of each row opens the full dialog for a custom amount with an optional reason
+- `show_dialog: false` hides the `⋯` buttons entirely if you only want fixed amounts
+- All amounts are configurable in the card editor — enter comma-separated values e.g. `1, 2, 5, 10, 25`
+- Quick buttons fire without a reason — use `⋯` when you want to log a reason
+
+---
+
+## Reorder Card
+
+
+
+**Purpose:** Drag-and-drop interface to set the display order of chores for each child.
+
+**Default header colour:** Teal `#16a085`
+
+```yaml
+type: custom:taskmate-reorder-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a
+title: Reorder Chores
+header_color: "#16a085"
+```
+
+**Behaviour:**
+- Drag chore rows up and down within each time category group
+- Click **Save Order** to apply — the order is stored per-child
+- Shows unsaved changes indicator when you have moved items
+
+---
+
+## Parent Dashboard Card
+
+
+
+**Purpose:** All-in-one parent control centre with four tabs.
+
+**Default header colour:** Crimson `#c0392b`
+
+```yaml
+type: custom:taskmate-parent-dashboard-card
+entity: sensor.taskmate_overview
+title: Parent Dashboard
+quick_points_amount: 5 # points per +/- button press
+show_claims: true # show the Claims tab
+header_color: "#c0392b"
+```
+
+**Tabs:**
+
+| Tab | Content |
+|-----|---------|
+| **Overview** | All children's today progress bars and points |
+| **Approvals** | Pending chore completions with approve/reject — evidence-photo thumbnails render inline (see [Photo Proof](Photo-Proof.md)) |
+| **Claims** | Pending reward claims with approve/reject |
+| **Points** | Quick +/- buttons per child |
+
+---
+
+## Overview Card
+
+
+
+**Purpose:** At-a-glance parent summary of all children.
+
+**Default header colour:** Violet `#8e44ad`
+
+```yaml
+type: custom:taskmate-overview-card
+entity: sensor.taskmate_overview
+title: TaskMate
+approvals_entity: sensor.taskmate_pending_approvals # optional — override for pending approvals count
+show_parent_actions: true # (v6.2.0) false = tiles don't expand to complete on a child's behalf
+header_color: "#8e44ad"
+```
+
+**Shows per child:**
+- Today's chore progress bar (approved completions / chores due today)
+- Current points balance
+- Pending approval chip (if any)
+- Footer totals: children count, done today, total points
+
+> **Note:** Progress counts only chores due today. Chores with `due_days` set are excluded from the denominator on days they are not scheduled. Chores with no `due_days` set are always included.
+
+---
+
+## Activity Card
+
+
+
+**Purpose:** Scrollable timeline of all activity.
+
+**Default header colour:** Steel Blue `#2471a3`
+
+```yaml
+type: custom:taskmate-activity-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+max_items: 30
+show_filter_chips: true # All / Chores / Rewards / Adjustments chip bar
+accent_stripes: true # coloured left stripe per row
+show_relative_time: true # "5m ago" / "2h ago" labels
+show_undo: true # set false to hide undo buttons (kid-friendly dashboards)
+header_color: "#2471a3"
+```
+
+**Shows:**
+- Chore completions (approved and pending)
+- Manual point adjustments (add/remove)
+- Bonus point events (weekend multiplier, streak milestones, perfect week)
+- Reward claim events
+
+Grouped by Today / Yesterday / date.
+
+Reversible events show a per-action **Undo (↩)** button that rolls the event back. Set `show_undo: false` to hide these buttons — ideal for a children's dashboard where kids should see what they earned but not be able to reverse their own activity.
+
+**Redesign options:**
+
+The card was redesigned for clearer visual hierarchy, in-card filtering, and accessibility. Three per-card switches let each instance opt in or out of those changes independently. All three default to on, so existing cards keep the redesigned look.
+
+| Option | Default | Effect |
+|--------|---------|--------|
+| `show_filter_chips` | `true` | Shows the **All / Chores / Rewards / Adjustments** chip bar below the header for filtering the timeline in place |
+| `accent_stripes` | `true` | Adds a coloured left stripe to each row encoding approved / pending / penalty / reward by colour |
+| `show_relative_time` | `true` | Shows a relative `5m ago` / `2h ago` label alongside the absolute time |
+| `show_undo` | `true` | Shows the per-row **Undo (↩)** button. Set `false` for a kid-friendly dashboard so children can't reverse their own activity |
+
+All four are available in the visual card editor.
+
+---
+
+## Streak Card
+
+
+
+**Purpose:** Shows streak history and achievement badges.
+
+**Default header colour:** Red `#e74c3c`
+
+```yaml
+type: custom:taskmate-streak-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+streak_days_shown: 14 # dot history length
+header_color: "#e74c3c"
+```
+
+**Shows:**
+- Current and best streak numbers
+- Dot history grid (green = completed, grey = missed)
+- Achievement badges for milestones (First!, 3 days, 7 days, 14 days, 30 days, etc.)
+- **(v6.0.0)** The ❄️ [streak freeze](Streak-Freezes.md) tokens each child holds, while streak freezes are on
+
+---
+
+## Weekly Card
+
+
+
+**Purpose:** Monday–Sunday view with bar chart.
+
+**Default header colour:** Green `#27ae60`
+
+```yaml
+type: custom:taskmate-weekly-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+header_color: "#27ae60"
+```
+
+**Shows:**
+- Daily bar chart (approved completions only)
+- Headline stats: chores, points, days active
+- Per-child breakdown
+- Week date range
+
+---
+
+## Points Graph Card
+
+
+
+**Purpose:** Line graph of points over time.
+
+**Default header colour:** Burnt Orange `#d35400`
+
+```yaml
+type: custom:taskmate-graph-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+days: 14 # date range: 3–90
+header_color: "#d35400"
+```
+
+**Features:**
+- Canvas-based (works on mobile HA app)
+- Multiple children shown as colour-coded lines
+- Hover/touch tooltip showing values per day
+
+---
+
+## Reward Progress Card
+
+
+
+**Purpose:** Full-screen motivational display for a single reward. Designed for wall-mounted tablets.
+
+**Default header colour:** Deep Purple `#7d3c98`
+
+```yaml
+type: custom:taskmate-reward-progress-card
+entity: sensor.taskmate_overview
+reward_id: abc123 # required — see Finding IDs in Getting Started
+child_id: a8c8376a # optional
+title: Reward Goal
+header_color: "#7d3c98"
+```
+
+**Shows:**
+- Large reward icon with animated progress bar
+- Points progress and percentage
+- Pulsing "Ready to claim!" badge when affordable
+
+---
+
+## Leaderboard Card
+
+
+
+**Purpose:** Competitive ranking of all children.
+
+**Default header colour:** Gold `#b7950b`
+
+```yaml
+type: custom:taskmate-leaderboard-card
+entity: sensor.taskmate_overview
+sort_by: points # points | streak | weekly | career | season
+show_streak: true
+show_weekly: true
+header_color: "#b7950b"
+```
+
+**Behaviour:**
+- Top 3 get gold/silver/bronze styling
+- For single-child households: automatically shows personal bests (best streak, total chores, weekly points, total earned) instead of a ranking
+- **`sort_by: season`** ranks children by their points earned in the current calendar month and shows a champion banner naming the latest monthly winner. The leaderboard becomes a fresh contest that resets on the 1st of each month — see [Leaderboard Seasons](Leaderboard-Seasons.md)
+
+---
+
+## Penalties Card
+
+
+
+**Purpose:** Create, manage, and apply point penalties to children.
+
+**Default header colour:** Red `#e74c3c`
+
+```yaml
+type: custom:taskmate-penalties-card
+entity: sensor.taskmate_overview
+title: Penalties # optional — custom card title
+show_parent_actions: true # (v6.2.0) false = no Apply or edit controls
+header_color: "#e74c3c"
+```
+
+**Behaviour:**
+- View all defined penalties with name, points, icon, and assigned children
+- Toggle **Edit Mode** to add, edit, or delete penalty definitions
+- Apply a penalty to a child with one tap — points are deducted immediately
+- Penalties appear in the Activity Card timeline
+
+See [Penalties](Penalties.md) for service call details and automation examples.
+
+---
+
+## Bonuses Card
+
+
+
+**Purpose:** Create, manage, and apply point bonuses to children.
+
+**Default header colour:** Green `#2e7d32`
+
+```yaml
+type: custom:taskmate-bonuses-card
+entity: sensor.taskmate_overview
+title: Bonuses # optional — custom card title
+show_parent_actions: true # (v6.2.0) false = no Apply or edit controls
+header_color: "#2e7d32"
+```
+
+**Behaviour:**
+- View all defined bonuses with name, points, icon, and assigned children
+- Toggle **Edit Mode** to add, edit, or delete bonus definitions
+- Apply a bonus to a child with one tap — points are awarded immediately
+- Bonuses appear in the Activity Card timeline
+
+See [Bonuses](Bonuses.md) for service call details and use cases.
+
+---
+
+## Points Display Card
+
+
+
+**Purpose:** Visual points display with three display modes — single child, multi-child grid, or cumulative family total.
+
+**Default header colour:** Purple `#9b59b6`
+
+```yaml
+type: custom:taskmate-points-display-card
+entity: sensor.taskmate_overview
+mode: single # single | multi | cumulative
+child_id: a8c8376a # required for single mode
+show_streak: true # show streak info
+show_weekly: true # show weekly stats
+show_rank: true # show rank medal in multi/cumulative modes
+header_color: "#9b59b6"
+```
+
+**Modes:**
+
+| Mode | Description |
+|------|-------------|
+| `single` | Large display for one child — shows avatar, points balance, streak, and weekly stats |
+| `multi` | Grid of all children with points and optional rank medals |
+| `cumulative` | Family total — combined points across all children |
+
+---
+
+## Calendar Card
+
+
+
+**Purpose:** Calendar view showing chore assignments and completions across days. Navigate with Prev/Next/Today buttons.
+
+**Default header colour:** Blue `#3498db`
+
+```yaml
+type: custom:taskmate-calendar-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+title: Task Calendar
+header_color: "#3498db"
+```
+
+**Behaviour:**
+- Shows a day-by-day view of chore assignments based on scheduling rules
+- Colour-codes chores by completion state (done / pending / not yet)
+- Respects all schedule modes: specific days, recurring, and one-shot
+- Handles assignment modes (alternating/random/balanced) — only shows the assigned child for that day
+- Navigate between days with Prev / Next / Today buttons
+
+---
+
+## Badges Card
+
+
+
+**Purpose:** Grid display of all achievement badges for a child — earned badges in full tier colour, locked badges greyed with progress bars.
+
+**Default header colour:** Purple `#764ba2`
+
+```yaml
+type: custom:taskmate-badges-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — filter to one child
+header_color: "#764ba2"
+```
+
+**Features:**
+- Earned badges show icon, name, earned date, and point bonus in tier-specific colour
+- Locked badges show greyed out with dashed border and a progress bar showing closest-criterion completion percentage
+- Tier filter dropdown: All / Bronze / Silver / Gold / Platinum
+- Newly-earned badges animate with a pop + shimmer effect
+- Listens for `taskmate_badge_earned` bus events for real-time highlighting
+
+See [Achievement Badges](Achievement-Badges.md) for full details on tiers, criteria, and services.
+
+---
+
+## Family Goal Card
+
+
+
+**Purpose:** Shows the household's progress toward the shared co-op family goal — everyone's combined points measured against a single target, with the reward shown beneath.
+
+**Default header colour:** Teal `#16a085`
+
+```yaml
+type: custom:taskmate-family-goal-card
+entity: sensor.taskmate_overview
+title: Family Goal # optional — custom card title
+header_color: "#16a085"
+```
+
+**Behaviour:**
+- Displays a progress bar from the combined family balance toward the goal target, with a percentage
+- Shows the goal's reward, and a celebration state once the target is reached
+- If no family goal is enabled, the card shows a friendly "no goal set" placeholder
+
+The goal itself is enabled and configured in [Settings](Settings.md). See [Family Goals](Family-Goals.md) for the full feature.
+
+---
+
+## Photo Gallery Card
+
+
+
+**Purpose:** A history grid of submitted chore-evidence photos, captioned with the child, chore, and date.
+
+**Default header colour:** Slate `#5d6d7e`
+
+```yaml
+type: custom:taskmate-photo-gallery-card
+entity: sensor.taskmate_activity
+title: Proof Photos # optional — custom card title
+max: 40 # optional — limit the number of photos shown
+header_color: "#5d6d7e"
+```
+
+**Behaviour:**
+- Renders a thumbnail grid of completions that carried a proof photo
+- Tap a thumbnail to open the full image in a new tab
+- Completions still awaiting approval are flagged **pending** in their caption
+- Note this card reads the **activity** sensor (`sensor.taskmate_activity`), not the overview sensor
+
+See [Photo Proof](Photo-Proof.md) for how proof photos are captured and reviewed.
+
+---
+
+## Kiosk Card
+
+
+
+**(v6.0.0)** **Purpose:** A full-screen card for a shared wall tablet. Each child taps their face, types their PIN if they have one, and sees only their own chores with big **Done** buttons, plus their points, streak and next-reward progress. See [Kiosk Mode](Kiosk-Mode.md).
+
+**Default header colour:** Purple `#9b59b6`
+
+```yaml
+type: custom:taskmate-kiosk-card
+entity: sensor.taskmate_overview
+title: The Smiths # optional — shown in the top bar
+timeout: 60 # seconds without a tap before returning to the picker (15–600)
+warn_before_return: true # full-screen "Still there?" countdown for the last 10 seconds
+show_points: true # points and level
+show_streak: true
+show_reward_progress: true # next reward progress
+show_picker_progress: true # "3 of 6 done" under each face
+play_sounds: true # (v6.2.0) completion and undo sounds
+show_confetti: true # (v6.2.0) confetti on Done
+show_completion_popup: true # (v6.2.0) "AWESOME! You did it!" popup with the points
+show_bounties: false # (v6.3.0) Bounty Board section: claim, finish and give back bounties
+completed_mode: show # (v7.0.0) show | hide — done and waiting-for-approval chores
+elapsed_time_mode: show # (v7.0.0) show | dim | hide — time-of-day chores whose part of the day has passed
+ambient_mode: "off" # (v7.0.0) off | progress | photos — what the picker turns into when nobody's using it
+ambient_after: 120 # (v7.0.0) seconds untouched before ambient mode starts (30–1800)
+show_raffle_draws: true # (v7.0.0) spin the names and land on the winner when a raffle is drawn
+children: # optional — order and PINs; omit to show every child
+ - child_id: a8c8376a
+ require_pin: true
+ - child_id: ef19c561
+ require_pin: false
+header_color: "#9b59b6"
+```
+
+**Behaviour:**
+- The card goes back to the picker after the timeout, or straight after the all-done celebration
+- **Celebrations (v6.2.0)** — tapping **Done** plays the chore's completion sound, drops confetti and shows the "AWESOME! You did it!" popup with the points, the same as the child card. `default_sound` and `undo_sound` work as on the child card (YAML only). See [Kiosk Mode](Kiosk-Mode.md#celebrations)
+- **PINs** are 4 digits, set per child by a parent under **Children → Edit** in the admin panel. They are stored hashed and never appear in the card's YAML. Five wrong tries lock the keypad, for longer after each lockout. A child with no PIN goes straight in
+- Photo, timed and open-ended chores are shown greyed out under "Do these on your phone" and don't stop "all done"
+- **Bounties (v6.3.0)** — with `show_bounties: true` a child can claim, finish (with a photo from the tablet if one is needed) and give back bounties. Off by default. See [Kiosk Mode](Kiosk-Mode.md#bounties)
+- **Hide completed (v7.0.0)** — `completed_mode: hide` drops done and waiting chores from the list. They still count towards the "3 of 6 done" total, but can't be undone from the kiosk
+- **Missed chores (v7.0.0)** — `elapsed_time_mode: dim` greys out a morning/afternoon/evening/night chore once its part of the day has passed, and `hide` removes it. Either way it can't be ticked off and leaves the day's total. `show` (default) keeps it tappable
+- **Ambient mode (v7.0.0)** — with `ambient_mode: progress` the picker turns into a clock with every child's progress and any open raffles after `ambient_after` seconds untouched; `photos` shows a slideshow of chore photos instead. The first tap only wakes it. See [Kiosk Mode](Kiosk-Mode.md#ambient-mode)
+- **Offline taps (v7.0.0)** — a **Done** tapped while Home Assistant can't be reached is kept as "Waiting to send" and sent when the connection is back. See [Kiosk Mode](Kiosk-Mode.md#offline-taps)
+- **Raffle draws (v7.0.0)** — when a [raffle](Raffles.md) is drawn the tablet spins the names and lands on the winner, once per draw. Turn off with `show_raffle_draws: false`
+- Quantity chores join photo, timed and open-ended chores under "Do these on your phone"
+- There are no parent controls and no reward claiming on the kiosk
+- If "Require a linked account per child" is on, the tablet shows "Ask a grown-up" rather than getting around it
+
+---
+
+## Bounty Card
+
+
+
+**(v6.0.0)** **Purpose:** One child's view of the [Bounty Board](Bounty-Board.md): the one-off jobs they can claim, their current claim, and recently finished jobs.
+
+**Default header colour:** Orange `#e67e22`
+
+```yaml
+type: custom:taskmate-bounty-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # required — whose bounty board this is
+title: Bounties # optional
+header_color: "#e67e22"
+```
+
+**Behaviour:**
+- **Claim** locks a bounty to the child for its claim time; a child can hold one claim at a time
+- **Give back** returns it to the board; **Done** sends it for approval (with a photo when the bounty asks for one)
+- A countdown shows how long the claim has left. If it runs out the bounty goes back on the board
+- Bounties are posted and managed by parents on the admin panel's **Bounties** page
+
+---
+
+## Wishlist Card
+
+
+
+**(v6.0.0)** **Purpose:** One child's [Wishlist](Wishlist.md): the things they want, how much they've saved, and pledges from family.
+
+**Default header colour:** Pink `#e91e63`
+
+```yaml
+type: custom:taskmate-wishlist-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # required — whose wishlist this card shows
+title: Mia's wishes # optional — leave out for "'s Wishlist"
+header_color: "#e91e63"
+```
+
+**Behaviour:**
+- The child adds a wish (name, suggested target, link, picture); it waits for a parent to approve it on the admin panel's **Wishlists** page
+- The child moves points into an approved wish, and can take their own savings back out (never pledged points)
+- Pledges show as a separate stripe on the progress bar, with a chip per person
+- Once a wish is fully funded, **Ask to redeem** turns it into a normal reward claim
+- Up to 5 wishes per child at once
+
+---
+
+## Recap Card
+
+
+
+**(v6.0.0)** **Purpose:** Plays a child's [Recaps](Recaps.md) as a "Wrapped"-style story: chores done, points earned, top chore, longest streak, best day, badges and rewards, and how it compares with the previous period.
+
+**Default header colour:** Purple `#9b59b6`
+
+```yaml
+type: custom:taskmate-recap-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # required — whose recaps this card shows
+title: My recap # optional
+default_frequency: monthly # optional — which recap to open when there's nothing new (weekly | monthly | every_3_months | every_6_months | every_9_months | yearly)
+autoplay: false # true = move to the next slide every few seconds
+header_color: "#9b59b6"
+```
+
+**Behaviour:**
+- A new recap opens first; older ones are one tap away
+- **Save as image** lets the child keep or share a slide
+- Nothing shows until a parent turns recaps on in **Settings → Recaps**
+
+---
+
+## Auction Card
+
+
+
+**(v6.0.0)** **Purpose:** One child's view of [Chore Auctions](Chore-Auctions.md): the auctions they may bid on, their own bid, and recent results.
+
+**Default header colour:** Deep purple `#5e35b1`
+
+```yaml
+type: custom:taskmate-auction-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # required — whose auctions and bids this card shows
+title: Auctions # optional
+header_color: "#5e35b1"
+```
+
+**Behaviour:**
+- The child bids the fewest points they would do the chore for. **The lowest bid wins**; ties go to the earliest bid
+- The child only ever sees their own bid, how many bids are in, and the winning price once bidding closes
+- Changing a bid is allowed until it closes, but moves it to the back of the queue for tie-breaks
+- Auctions are opened by parents on the admin panel's **Auctions** page
+
+---
+
+## Chore Board Card
+
+
+
+**(v6.1.0)** **Purpose:** The admin panel's **Today** board on a dashboard. Every child's chores for today in one grid, with time periods down the side and children across the top. Good on a shared kitchen tablet.
+
+**Default header colour:** Indigo `#3f51b5`
+
+```yaml
+type: custom:taskmate-chore-board-card
+entity: sensor.taskmate_overview
+children: # optional — child IDs to show (default: all)
+ - a8c8376a
+default_view: today # optional — today | week
+show_week: true # optional — show the "This week" tab
+tap_to_complete: true # optional — false gives a view-only board
+show_legend: true # optional — status key under the board
+hide_done_periods: false # optional — hide a time period once all its chores are done
+title: Chore board # optional
+show_parent_actions: true # optional (v6.2.0) — false = Undo follows the child's undo window
+header_color: "#3f51b5"
+```
+
+**Behaviour:**
+- Each child's column header shows done/total for today. Each chore shows its status: **done** (green), **awaiting approval** (amber), **to do** or **missed** (red). Chores with a daily limit show progress like `1/3`
+- **Tap a to-do or missed chore** to complete it for that child. If the chore has a button entity the card presses it, so automations on the button fire; otherwise it calls `taskmate.complete_chore`. The chore's completion sound plays and a toast offers **Undo** (a parent's Undo rejects the completion; a child can undo inside their [undo window](Child-Undo-Window.md))
+- Done and awaiting-approval chips can't be tapped, so a passing tap can't undo anyone's chore
+- Photo, timed, open-ended, teamwork and (v7.0.0) quantity chores carry a small icon and can't be finished from the board. Tapping one says to finish it on the child's card
+- **This week** shows each child's done/total for the last 7 days. Days before TaskMate started recording show as grey
+- With a single child in `children`, the card becomes a simple list grouped by time of day with a progress bar
+- Reads `sensor.taskmate_chore_board`, so it works on a non-admin login such as a wall tablet
+
+---
+
+## Sticker Chart Card
+
+
+
+**(v6.4.0)** **Purpose:** A young child's whole day as stickers to tap. Every job due today is a big tile, the points they've saved show as a row of stickers, and blocks fill towards the reward they're saving for. Made for a wall tablet. See [Sticker Chart Card](Sticker-Chart-Card.md) for the full guide.
+
+```yaml
+type: custom:taskmate-sticker-chart-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — leave out for every child, side by side
+reward_id: abc123 # optional — default: the cheapest reward not yet affordable
+goal: reward # optional — reward | week
+title: Ellie's chart # optional — default "{name}'s Sticker Chart"
+columns: 4 # optional — job tiles per row, 2–6
+show_today: true # optional — the "Today: x / y jobs done" line
+show_claim: true # optional — the Claim button
+allow_undo: true # optional — press and hold to take a sticker back (parents only)
+sound: true # optional — play the chore's completion sound
+show_adults: false # optional (v6.4.0) — include adult profiles
+```
+
+**Behaviour:**
+- **Tap** a job to mark it done, through the chore's button entity if it has one. A celebration pops up, and a bigger one when the day is finished
+- **Press and hold** a done job to undo it. Only a parent can
+- Jobs waiting for approval show amber with ⏳. Photo-proof jobs show 📷 and are finished on the child card; open-ended and (v7.0.0) quantity chores aren't shown
+- **Claim** needs two taps, and the claim goes to a parent for approval
+- `goal: week` makes the stickers and blocks count this week's points against everything the week's jobs could pay, instead of the reward
+- The same chart powers the admin panel's [Log a past job](Logging-Past-Jobs.md) dialog
+
+---
+
+## Pet Card
+
+
+
+**(v7.0.0)** **Purpose:** A child's [virtual pet](Virtual-Pets.md). Before adoption the card is the adoption form: pick a dragon, cat, dog, bunny, dino or unicorn and give it a name. After that the pet hatches from an egg and grows as the child does chores.
+
+**Default header colour:** Teal `#16a085`
+
+```yaml
+type: custom:taskmate-pet-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # required — whose pet this is
+title: Sparky # optional — default: the pet's name
+header_color: "#16a085"
+```
+
+**Behaviour:**
+- The pet grows from egg to baby, little, big and fully grown. A bar shows how far it is to the next step
+- It is happy on days the child does a chore, proud of a streak, and sleepy after a missed day or two. Nothing is ever lost: a sleepy pet perks up with the next chore
+- Accessories (bow, top hat, scarf, crown) unlock as the child goes up [levels](Levels-and-XP.md)
+- After fully grown, whatever the parents switched on in Settings: its home fills up, it turns legendary gold, it lays an egg the child hatches into a new pet (earlier pets stay in the pet family row), and it gains pet levels
+- A short "evolving" moment plays the first time each device sees the pet grow
+- Shows "Pets are switched off" until a parent turns pets on in **Settings → Virtual pets**
+
+---
+
+## Raffle Card
+
+**(v7.0.0)** **Purpose:** [Raffles](Raffles.md): children spend points on tickets, one ticket is one chance, and one winner is drawn at the time the parent picked. With a `child_id` it is that child's card, for buying tickets and seeing their chance. Without one it is a family view for a wall tablet: everyone's tickets, no buying.
+
+**Default header colour:** Purple `#8e44ad`
+
+```yaml
+type: custom:taskmate-raffle-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — leave out for the family view (no buying)
+title: Raffles # optional
+show_reveal: true # optional — spin the names and land on the winner when a raffle is drawn
+header_color: "#8e44ad"
+```
+
+**Behaviour:**
+- Each open raffle shows its prize, ticket price, per-child limit, how many tickets are in and a countdown to the draw
+- On a child's card, **Buy** spends points through `taskmate.buy_raffle_tickets` and shows "You have 3 tickets · 25% chance"
+- A drawn raffle stays on the card for a day with its winner; a called-off one says the tickets were refunded
+- The draw animation plays once per browser, when a raffle is drawn while the card is on screen or within the last ten minutes
+- Raffles are set up by parents on the admin panel's **Raffles** tab. A raffle limited to some children is only shown on their cards
+
+---
+
+## Completion Sounds
+
+The child card plays a sound when a chore is ticked off. All synth sounds use the Web Audio API — no external files needed.
+
+| Sound | Type | Description |
+|-------|------|-------------|
+| `coin` | Synth | Classic video game coin collect |
+| `levelup` | Synth | Triumphant ascending arpeggio |
+| `fanfare` | Synth | Celebratory trumpet fanfare |
+| `chime` | Synth | Pleasant bell chime |
+| `powerup` | Synth | Ascending sweep with sparkle |
+| `undo` | Synth | Sad descending "womp womp" (played on undo) |
+| `fart1`–`fart10` | Audio file | Real fart sounds (CC0, BigSoundBank.com) |
+| `fart_random` | Audio file | Random fart sound 1–10 |
+| `none` | — | No sound |
+
+**Fart sounds** require audio files at `/config/www/taskmate/fart1.mp3` through `fart10.mp3`.
+
+**Priority:** chore-level `completion_sound` → card `default_sound` → `coin`
+
+You can preview sounds using the `taskmate.preview_sound` service from Developer Tools.
diff --git a/wiki/Difficulty-Tiers.md b/wiki/Difficulty-Tiers.md
new file mode 100644
index 00000000..8f0391ab
--- /dev/null
+++ b/wiki/Difficulty-Tiers.md
@@ -0,0 +1,87 @@
+# Difficulty Tiers
+
+Every chore carries a difficulty tier. The points a chore awards are its base points multiplied by the tier's multiplier, so harder chores can be worth more without re-entering point values by hand.
+
+
+
+---
+
+## Tiers and Default Multipliers
+
+| Tier | Default Multiplier | Effect on a 10-point chore |
+|------|--------------------|----------------------------|
+| `easy` | ×0.5 | 5 points |
+| `medium` | ×1.0 | 10 points |
+| `hard` | ×2.0 | 20 points |
+
+**Medium is the neutral baseline (×1.0) and is the default.** Chores created before difficulty tiers existed default to medium, so they keep their exact award value — nothing changes unless you set a chore to easy or hard.
+
+The awarded total is rounded to the nearest whole number and never goes below zero.
+
+---
+
+## Setting a Chore's Difficulty
+
+Set difficulty in the **Difficulty** selector in the chore dialog (add and edit) of the [Admin Panel](Admin-Panel.md), or pass `difficulty` to the `taskmate.add_chore` service. Valid values are `easy`, `medium`, `hard`; anything else falls back to medium.
+
+The child card shows the **effective** (post-multiplier) points, so a hard 10-point chore reads as 20.
+
+---
+
+## Difficulty Badge on the Child Card
+
+Since v4.0.1, children also see the difficulty tier directly on each chore as a small badge:
+
+| Tier | Badge |
+|------|-------|
+| `easy` | **Easy** badge |
+| `medium` | no badge (it is the baseline) |
+| `hard` | **Hard** badge |
+
+Medium shows no badge, so a chore card stays uncluttered for the common case. Previously the tier was only visible indirectly through the (post-multiplier) points value.
+
+---
+
+## Editing the Multipliers
+
+The per-tier multipliers are configurable in the [Admin Panel](Admin-Panel.md) under **Settings → Difficulty multipliers**. There are three inputs:
+
+| Setting | Default | Range |
+|---------|---------|-------|
+| `difficulty_multiplier_easy` | 0.5 | 0.0–10.0 |
+| `difficulty_multiplier_medium` | 1.0 | 0.0–10.0 |
+| `difficulty_multiplier_hard` | 2.0 | 0.0–10.0 |
+
+Changing a multiplier affects all chores at that tier going forward. Multipliers are global, not per-chore.
+
+> **Note:** Keeping medium at ×1.0 is recommended — it is the baseline that preserves existing chore values. You can change it, but every medium chore (including legacy ones) will then be rescaled.
+
+---
+
+## Interaction with Other Features
+
+- **Base points** are what you enter on the chore; the multiplier scales them at award time on both completion and approval.
+- **Early bonus / late penalty** (see [Chores](Chores.md)) are applied *after* the difficulty multiplier — the tier scales the base, then the time adjustment is added or subtracted.
+- **Timed chores** earn by rate window, not base points, so the difficulty multiplier does not apply to them.
+
+---
+
+## Sensor Attributes
+
+Each chore in `sensor.taskmate_overview` → `chores` emits difficulty fields only when they are non-default, to keep the payload compact:
+
+| Attribute | When emitted | Description |
+|-----------|--------------|-------------|
+| `difficulty` | Only when not `medium` | The chore's tier (`easy` / `hard`) |
+| `effective_points` | Only when it differs from base `points` | The post-multiplier award value |
+
+A plain medium chore emits neither field, so cards can assume base points unless `effective_points` is present.
+
+The chore completion event (`taskmate_chore_completed`) reports the effective `points` plus a `difficulty` field.
+
+---
+
+## Related
+
+- [Chores](Chores.md) — chore configuration and the difficulty field
+- [Admin Panel](Admin-Panel.md) — where the selector and multiplier inputs live
diff --git a/wiki/Dynamic-Chore-Visibility.md b/wiki/Dynamic-Chore-Visibility.md
new file mode 100644
index 00000000..d7c6ef5d
--- /dev/null
+++ b/wiki/Dynamic-Chore-Visibility.md
@@ -0,0 +1,227 @@
+# Dynamic Chore Visibility
+
+## Overview
+
+
+
+Dynamic Chore Visibility allows you to conditionally show or hide chores on the child card based on the state of any Home Assistant entity. This powerful feature enables you to create context-aware chore lists that automatically appear or disappear based on real-world conditions.
+
+**Example Use Cases:**
+- Show dishwasher-loading chores only when the dishwasher is running
+- Show watering chores only when soil moisture drops below a threshold
+- Show yard work only when it's warm enough outside
+- Hide chores when guests are visiting using an input_boolean
+
+## How It Works
+
+When you create or edit a chore, you can set three optional fields:
+
+1. **Visibility Entity** — A Home Assistant entity ID that controls the chore's visibility
+2. **Visibility Operator** — How to compare the entity's state with your target value
+3. **Visibility State** — The target value to compare against
+
+The chore appears on the child card **only when** the visibility condition is met.
+
+### Example Configuration
+
+| Field | Value | Meaning |
+|-------|-------|---------|
+| Visibility Entity | `binary_sensor.dishwasher` | Watch the dishwasher entity |
+| Visibility Operator | `Equals` | When it matches exactly |
+| Visibility State | `on` | The "on" state |
+
+**Result:** The chore only appears when the dishwasher is running.
+
+## Supported Entity Types
+
+Visibility works with any Home Assistant entity:
+- **Binary Sensors** — `binary_sensor.dishwasher`, `binary_sensor.door_open`
+- **Sensors** — `sensor.temperature`, `sensor.soil_moisture`, `sensor.battery_percent`
+- **Input Booleans** — `input_boolean.guest_mode`, `input_boolean.school_day`
+- **Switches** — `switch.laundry_room`, `switch.office_light`
+- **Numbers** — `number.temperature_threshold`
+- **Any other entity with a state**
+
+## Common Use Cases
+
+### Equipment-Based Chores
+
+**Show chores only when equipment is in use:**
+
+```
+Entity: binary_sensor.dishwasher
+Operator: Equals
+State: on
+→ Shows "Load dishwasher" only when dishwasher is running
+```
+
+```
+Entity: binary_sensor.dryer
+Operator: Equals
+State: on
+→ Shows "Fold laundry" only when dryer is running
+```
+
+### Sensor-Based Chores
+
+**Show chores based on numeric thresholds:**
+
+```
+Entity: sensor.soil_moisture
+Operator: ≤ (Less than or equal)
+State: 30
+→ Shows "Water plants" when moisture ≤ 30%
+```
+
+```
+Entity: sensor.temperature
+Operator: ≥ (Greater than or equal)
+State: 20
+→ Shows "Yard work" when temperature ≥ 20°C
+```
+
+### Conditional Availability
+
+**Show/hide based on family status:**
+
+```
+Entity: input_boolean.guest_mode
+Operator: Not Equal
+State: on
+→ Shows chores only when guests are NOT visiting
+```
+
+```
+Entity: input_boolean.school_day
+Operator: Equals
+State: on
+→ Shows "Lunch prep" only on school days
+```
+
+### Time-Based Conditions
+
+**Use time-of-day helpers for scheduling:**
+
+```
+Entity: binary_sensor.is_daytime
+Operator: Equals
+State: on
+→ Shows outdoor chores only during daylight
+```
+
+## Technical Details
+
+### Numeric Comparison
+
+When using comparison operators (≥, ≤, >, <), the entity state is automatically converted to a number:
+
+- Valid: `sensor.temperature` with state `22.5` using operator `>`
+- Valid: `sensor.battery_percent` with state `75` using operator `≥`
+- Fallback: If conversion fails, string matching is used instead
+
+### String Matching
+
+For `Equals` and `Not Equal` operators:
+
+- Case-insensitive matching
+- Exact value required
+- Works with any state value: `on`, `off`, `home`, `away`, `running`, custom values, etc.
+
+### Entity Unavailability
+
+If the entity **does not exist at all** — deleted, renamed, or a typo in the id —
+the chore **defaults to visible**, so a broken reference can never silently hide
+a family's chores.
+
+An entity that exists but reports `unavailable` or `unknown` is a different
+case: those are ordinary state strings and are compared like any other value.
+They will not match `on`, so the chore **hides**. If an integration dropping
+offline shouldn't hide a chore, point the condition at something more stable, or
+use `Not Equal` so an unexpected state leaves the chore showing.
+
+- Parent services like `taskmate.complete_chore` still work on hidden chores
+- Check Home Assistant's Developer Tools > States to verify entity availability
+
+### Update Frequency
+
+Visibility checks happen every **30 seconds** (coordinator refresh interval). This means:
+- Changes to entity state take up to 30 seconds to affect chore visibility
+- This is a balancing act between responsiveness and performance
+- Consider this when setting up rapid state changes
+
+## Setting Up Visibility
+
+1. Open **TaskMate** in the Home Assistant sidebar
+2. Go to **Chores**
+3. Click **+ Add chore**, or the **✏** button on an existing chore's row
+4. Expand **Advanced — visibility & calendar publishing** and set:
+ - **Show when entity is** — Enter your entity ID
+ - **How to compare** — Select the operator
+ - **Value to compare** — Enter the target value
+5. Save the chore
+
+The chore will now appear/disappear based on the visibility condition.
+
+## Clearing Visibility
+
+To disable visibility filtering on a chore:
+
+1. Edit the chore
+2. Leave the **Show when entity is** field **blank**
+3. Save
+
+The chore will always be visible on the child card.
+
+## Limitations & Notes
+
+- **Single condition per chore** — Currently supports one visibility condition (AND/OR logic coming in future versions)
+- **30-second refresh** — Visibility updates every 30 seconds, not in real-time
+- **Card display only** — Visibility only hides chores from the child card. Parent API calls and services can still complete hidden chores
+- **Numeric conversion** — Non-numeric values fall back to string matching automatically
+
+## Troubleshooting
+
+### Chore isn't appearing when I expect it to
+
+1. **Check the entity exists** — Go to Developer Tools > States and search for your entity
+2. **Verify the state** — What's the current state value?
+3. **Test the operator** — Is the state actually matching your condition?
+4. **Wait 30 seconds** — Visibility updates every 30 seconds
+5. **Check entity type** — For numeric operators, ensure the entity can be converted to a number
+
+### Entity state shows "unavailable" or "unknown"
+
+This means the entity isn't providing data to Home Assistant:
+- Check the integration that provides this entity
+- Restart Home Assistant
+- Note the chore will **hide**, not show, while the state reads `unavailable` —
+ only a completely missing entity falls back to visible
+
+### Chore shows for both matching and non-matching states
+
+This usually means:
+- The `Visibility Entity` field is empty (clear it completely if you want to disable visibility)
+- The entity state doesn't match your `Visibility State` exactly
+- For numeric operators, the state might not be a valid number
+
+## Future Enhancements
+
+Planned improvements to visibility:
+- **Multiple conditions** — Combine visibility rules with AND/OR logic
+- **Instant updates** — Real-time visibility changes instead of 30-second interval
+- **Templates** — Pre-built visibility configurations for common scenarios
+- **Negation** — Hide when condition is met (inverse logic)
+
+## Questions or Issues?
+
+If you encounter problems with visibility:
+
+1. Check Home Assistant's logs for errors
+2. Verify your entity ID in Developer Tools > States
+3. Test manually in Developer Tools > Call Service
+4. Report issues on [GitHub Issues](https://github.com/tempus2016/taskmate/issues)
+
+## See also
+
+- [Visibility Configuration Guide](Visibility-Configuration-Guide.md) — a full end-to-end walkthrough of setting visibility up
+- [Visibility Operators Reference](Visibility-Operators-Reference.md) — every operator, with examples
diff --git a/wiki/Estimated-Minutes.md b/wiki/Estimated-Minutes.md
new file mode 100644
index 00000000..73b9ff2b
--- /dev/null
+++ b/wiki/Estimated-Minutes.md
@@ -0,0 +1,56 @@
+# Estimated Minutes
+
+Give a chore a rough time ("about 10 minutes") and the child card shows it beside the chore and adds the day up: **About 30 min left**. Children find "half an hour of jobs" much easier to face than a list of seven things, and you get a fairer view of who's doing the work, because a 30-minute job and a 2-minute one no longer both count as "one chore".
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Setting the Estimate
+
+**TaskMate panel → Chores → edit a chore → Minutes (estimate)**
+
+
+
+Whole minutes, 0–600. 0 (the default) means not set: the chore shows no time and doesn't add to the total.
+
+The estimate is set in the panel's chore editor (it's stored as the chore's `estimated_minutes`); the `add_chore` and `update_chore` services don't take it.
+
+---
+
+## On the Child Card
+
+- Every outstanding chore with an estimate shows a **⏱ ~10 mins** tag. It disappears once the chore is done.
+- The **Today's Chores** header shows **⏳ About 30 min left**: the estimates of everything still to do today, multiplied by how many times each is still owed (a chore done twice a day counts twice until the first is done). Chores not due today, still locked behind another chore, or already taken by someone else don't count.
+
+Both appear in every card design. To hide the total on a card:
+
+```yaml
+type: custom:taskmate-child-card
+entity: sensor.taskmate_overview
+child_id: 8e16ad66b23f404e
+show_minutes_left: false
+```
+
+In the editor it's **Show minutes of jobs left**. The per-chore tags stay.
+
+---
+
+## In the Fairness Report
+
+**TaskMate panel → Insights → Fairness** adds the minutes to each child's line: "9 chores · 52 Points · 53% · 95 min (54.3% of the time)".
+
+
+
+The minutes come from each approved chore's current estimate, so they only appear once some chores have one. The verdict (balanced or not) is still judged on the chore count; the minutes are a third way to look at it.
+
+---
+
+## Related
+
+- [Chores](Chores.md) — every chore field
+- [Insights](Insights.md) — the fairness report and the others
+- [Timed Tasks](Timed-Tasks.md) — chores that run a real timer
+- [Quantity Chores](Quantity-Chores.md) — "read 20 pages"
diff --git a/wiki/Event-Entities.md b/wiki/Event-Entities.md
new file mode 100644
index 00000000..4b3a3a8c
--- /dev/null
+++ b/wiki/Event-Entities.md
@@ -0,0 +1,123 @@
+# Event Entities
+
+TaskMate has always fired `taskmate_*` events on Home Assistant's event bus for YAML automations. **Event entities** put the same moments where the UI can see them: one entity per child, plus one for the family. In the automation editor you can now pick "When Vaiha's activity has event type *Chore approved*" from a list, without writing any YAML or looking up event names. On a dashboard, the entity shows the latest thing that happened.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## The Entities
+
+They're created automatically, on the TaskMate device:
+
+| Entity | Example ID | Covers |
+|--------|-----------|--------|
+| **{Child} activity** | `event.taskmate_vaiha_activity` | Everything about that one child |
+| **Family activity** | `event.taskmate_family_activity` | Family-wide moments |
+
+A new child gets their entity as soon as they're added. On Home Assistant 2026.6 and later, a new entity on a device that has an area gets the area in front of its ID (for example `event.kitchen_taskmate_vaiha_activity`), so check the real ID in **Settings → Entities**.
+
+The entity's state is the time of the latest event. Its `event_type` attribute says what happened, and the other attributes carry that event's details (child, chore, points and so on: the same data as the bus event, minus the timestamp).
+
+---
+
+## Event Types
+
+### On each child's entity
+
+| Event type | Shown as | Event type | Shown as |
+|-----------|----------|-----------|----------|
+| `chore_completed` | Chore completed | `challenge_completed` | Challenge completed |
+| `chore_approved` | Chore approved | `bonus_applied` | Bonus applied |
+| `chore_rejected` | Chore rejected | `penalty_applied` | Penalty applied |
+| `chore_approval_undone` | Chore approval undone | `surprise_bonus` | Surprise bonus |
+| `chore_auto_approved` | Chore auto-approved | `mandatory_missed` | Mandatory chore missed |
+| `reward_claimed` | Reward claimed | `team_chore_completed` | Team chore completed |
+| `reward_approved` | Reward approved | `points_gifted` | Points gifted |
+| `reward_rejected` | Reward rejected | `help_requested` | Help requested |
+| `badge_earned` | Badge earned | `mood_logged` | Mood logged |
+| `level_up` | Level up | `weekly_goal_reached` | Weekly goal reached |
+| `streak_updated` | Streak updated | `sick_day` | Sick day |
+| `streak_freeze_used` | Streak freeze used | `penalty_redeemed` | Penalty earned back |
+| `perfect_week` | Perfect week | `raffle_won` | Raffle won |
+| `weekly_target_reached` | Weekly target reached | `pet_evolved` | Pet grew up |
+| `quest_completed` | Quest completed | | |
+
+An event about more than one child lands on each of their entities: a [gift of points](Gifting-Points.md) on both the giver's and the receiver's, a [teamwork chore](Teamwork-Chores.md) on everyone in the team.
+
+### On the family entity
+
+| Event type | Shown as |
+|-----------|----------|
+| `family_goal_reached` | Family goal reached |
+| `season_champion` | Season champion |
+| `bounty_posted` | Bounty posted |
+| `scheduled_change_applied` | Scheduled change applied |
+| `raffle_drawn` | Raffle drawn |
+
+Events tied to a notification (help requested, weekly goal reached, penalty earned back, pet grew up, raffle drawn) reach the entities whether or not that notification is switched on.
+
+---
+
+## Using Them in the Automation Editor
+
+**Settings → Automations & scenes → Create automation**, then **Add trigger → Entity → State**. Pick the child's activity entity, set **Attribute** to *Event type* and **To** to the event you want. The editor offers the event types by name.
+
+
+
+The same automation in YAML:
+
+```yaml
+alias: Vaiha's chore approved
+triggers:
+ - trigger: state
+ entity_id: event.taskmate_vaiha_activity
+ attribute: event_type
+ to: chore_approved
+actions:
+ - action: persistent_notification.create
+ data:
+ title: Chore approved
+ message: >-
+ {{ state_attr('event.taskmate_vaiha_activity', 'chore_name') }}
+ is approved: +{{ state_attr('event.taskmate_vaiha_activity', 'points') }}
+```
+
+A trigger on the *Event type* attribute only fires when the type **changes**. To catch every occurrence, even two approvals in a row, trigger on the entity's state (it changes with every event) and check the type in a condition:
+
+```yaml
+triggers:
+ - trigger: state
+ entity_id: event.taskmate_vaiha_activity
+ not_from: unavailable
+conditions:
+ - condition: state
+ entity_id: event.taskmate_vaiha_activity
+ attribute: event_type
+ state: chore_approved
+```
+
+### Ideas
+
+| When | Then |
+|------|------|
+| `help_requested` on any child | Flash the kitchen light |
+| `level_up` | Play a fanfare on the living-room speaker |
+| `raffle_drawn` on the family entity | Announce the winner on the kiosk speaker |
+| `sick_day` | Skip the morning chore announcement for that child |
+
+---
+
+## Bus Events Still Work
+
+Nothing changes for existing automations: every `taskmate_*` bus event still fires, with the same data. The event entities are an extra way in. See [Automations](Automations.md) for the full list of bus events.
+
+---
+
+## Related
+
+- [Automations](Automations.md) — every TaskMate bus event and YAML examples
+- [Notifications](Notifications.md) — TaskMate's own pushes
+- [Sensor Reference](Sensor-Reference.md) — the other TaskMate entities
diff --git a/wiki/External-Lock-Screen-Shops.md b/wiki/External-Lock-Screen-Shops.md
new file mode 100644
index 00000000..5862b53f
--- /dev/null
+++ b/wiki/External-Lock-Screen-Shops.md
@@ -0,0 +1,101 @@
+# External Lock Screen Shops
+
+Let a separate lock-screen, kiosk, or parental-control system present the shop, while TaskMate stays the authority on points and approvals. The external system submits the child's normal reward claim and waits — it never grants anything itself.
+
+---
+
+## The Rule
+
+**A claim is a request, not a purchase.** Nothing is unlocked and no points move until a parent approves it.
+
+An external shop that unlocks on `taskmate_reward_claimed` has given the child a way to spend points they may not have, on something a parent never agreed to. Wait for `taskmate_reward_approved`.
+
+---
+
+## Reward Event Lifecycle
+
+| Event | Fired when | Correlation fields |
+|-------|-----------|-------------------|
+| `taskmate_reward_claimed` | A child creates a pending claim | `claim_id`, `child_id`, `reward_id`, `cost` |
+| `taskmate_reward_approved` | A parent approves the claim | `claim_id`, `child_id`, `reward_id`, `cost` |
+| `taskmate_reward_rejected` | A parent rejects the claim | `claim_id`, `child_id`, `reward_id` |
+
+All three also carry `timestamp`; the approved and rejected events add `child_name` and `reward_name`.
+
+`claim_id` is the same value across all three, so one claim can be followed from request to outcome. Use it to update a pending-purchase indicator and to deduplicate a handler that might see an event twice.
+
+---
+
+## Where The Points Actually Move
+
+Approval is the moment the purchase becomes real, but it is **not** always the moment points leave the child's balance. That depends on how the reward is funded.
+
+| Reward funding | When points leave the child's balance |
+|----------------|---------------------------------------|
+| Wallet — the normal case | On **approval**. `child.points` drops by the reward's cost. |
+| [Pool or jackpot](Pool-Mode-(Savings-Jars).md) with a filled pool | On **allocation**, earlier. Approval only clears the allocation records — the visible balance does not change. |
+
+If your shop tracks balances itself, do not assume `taskmate_reward_approved` means a deduction just happened. Read the child's points sensor after the event rather than subtracting `cost` yourself.
+
+---
+
+## The Safe Pattern
+
+One automation per reward-to-device mapping. Filter **both** the child and the reward, and act only on approval.
+
+```yaml
+alias: Release Alex's PC after an approved TaskMate reward
+mode: single
+triggers:
+ - trigger: event
+ event_type: taskmate_reward_approved
+conditions:
+ - condition: template
+ value_template: >-
+ {{ trigger.event.data.child_id == "alex-child-id"
+ and trigger.event.data.reward_id == "pc-time-reward-id" }}
+actions:
+ - action: switch.turn_off
+ target:
+ entity_id: switch.alex_pc_blocked
+```
+
+Find the ids in **Admin Panel → Children** and **→ Rewards**, or on the `sensor.taskmate_rewards` attributes.
+
+---
+
+## Key Points
+
+- **Keep a single unlock owner.** Use either TaskMate's own [Timed Unlock Rewards](Timed-Unlock-Rewards.md) for a reward *or* an external approval automation — never both on the same reward, or two systems will fight over the same switch.
+- **Fail closed.** An unrecognised child or reward id should do nothing. Never fall back to "unlock anyway".
+- **Never retry by re-claiming.** If your unlock action fails, leave the claim record alone and alert a parent. Submitting a second claim charges the child twice.
+- **Make the action idempotent.** The same approval may reach your handler more than once; turning a switch off twice must be harmless.
+- **Filter on ids, not names.** `child_name` and `reward_name` are for display and change whenever a parent renames something.
+
+---
+
+## Correlating Without Events
+
+If you would rather poll than listen to the bus, the same ids are on sensor attributes:
+
+| Source | What it gives you |
+|--------|-------------------|
+| `sensor.taskmate_pending_approvals` → `reward_claims[]` | Every pending claim, each with `claim_id`, `child_id`, `reward_id`, `cost` |
+| `sensor.taskmate_rewards` → `pending_reward_claims[]` | The same pending list, alongside the reward catalogue |
+| `sensor.taskmate_activity` → `recent_transactions[]` | Approved claims, where `transaction_id` **is** the claim id and `type` is `reward_approved` |
+
+Two limits make the event bus the better choice for anything that must not be missed:
+
+- **Rejections leave no trace.** A rejected claim is deleted outright, so it never appears in the activity feed. Polling can only see that it vanished from the pending list, and cannot tell you it was rejected rather than approved.
+- **The activity feed is capped at 20 entries** to stay under Home Assistant's recorder attribute limit. A busy family can push an approval out of the window before a slow consumer reads it.
+
+---
+
+## Related
+
+- [Rewards](Rewards.md) — costs, jackpots, spending caps and the claim flow
+- [Managing Rewards](Managing-Rewards.md) — the parent approval workflow
+- [Timed Unlock Rewards](Timed-Unlock-Rewards.md) — TaskMate's own built-in device unlocking
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — why approval doesn't always deduct
+- [Automations](Automations.md) — every TaskMate bus event
+- [Sensor Reference](Sensor-Reference.md) — all entities and their attributes
diff --git a/wiki/FAQ.md b/wiki/FAQ.md
new file mode 100644
index 00000000..2a152bc5
--- /dev/null
+++ b/wiki/FAQ.md
@@ -0,0 +1,149 @@
+# FAQ
+
+Common questions about TaskMate. If yours isn't answered here, please open an [issue](https://github.com/tempus2016/taskmate/issues).
+
+## General
+
+### Does TaskMate send my data anywhere?
+No. TaskMate is fully local-first. All child, chore, reward, and points data is stored inside your Home Assistant instance under `.storage/`. Nothing leaves your network.
+
+### What HA version do I need?
+Home Assistant 2024.7 or newer (matches the value in `hacs.json`).
+
+2024.7.0 is where `hass.http.async_register_static_paths` was introduced, which TaskMate uses to serve its dashboard cards. On anything older the integration fails to load rather than degrading. CI tests this floor directly, alongside current HA.
+
+### How do I back up my TaskMate data?
+Your normal Home Assistant backups include the `.storage/` directory, which is where TaskMate keeps everything. Nothing extra required.
+
+## Chores
+
+### What's the difference between "specific days" and "recurring" chore modes?
+- **Specific days**: show this chore on the selected days of the week (e.g. Monday / Wednesday / Friday).
+- **Recurring**: rolling window — show again every 2 days / weekly / every 2 weeks / monthly / every 3 months / every 6 months after the last completion.
+
+### Can I create a chore that only shows once?
+Yes — use **one-shot** chores. A one-shot chore is available the day it's created and automatically expires at midnight. Each assigned child has their own chance to complete it.
+
+### Can chores be conditional on a sensor?
+Yes. Set `visibility_entity`, `visibility_state`, and `visibility_operator` on a chore. For example: show *"Feed the cat"* only when `binary_sensor.cat_food_bowl` is `off`.
+
+## Rewards
+
+### What happens if a child tries to claim a reward they can't afford?
+In wallet mode, the Claim button is disabled and shows *"Not enough points"* on hover. In pool mode, the Redeem button only appears once the pool is full.
+
+### Can I mix wallet rewards and pool rewards on the same card?
+Yes — this is the main use case for the per-reward `pool_enabled` toggle. Short-term treats stay as wallet rewards (instant claim); long-term goals become pool rewards (savings jars).
+
+### What happens when I delete a reward?
+Any pending claims for it are removed, any pool allocations are cleared (points are not refunded to children), and the reward disappears from every rewards card.
+
+## Pool Mode
+
+### Do I have to use Pool Mode?
+No. It's entirely opt-in — both per-reward (admin toggle) and per-card (`enable_pool_mode: true`). Existing v2.x installs continue to work unchanged.
+
+### Can my child move points back out of a pool?
+No — by design. Allocated points are locked to teach commitment. If you need to reset a pool as a parent, delete the reward (which clears allocations) and recreate it.
+
+### What happens if I reject a pool-mode claim?
+The claim is removed but **the allocation stays full**. The child can hit Redeem again immediately. Rejection in pool mode means *"not this time, ask me again later"*. To permanently cancel a pool, delete the reward.
+
+### Why didn't the LEGO bar move when my child earned 10 points?
+In Pool Mode, earning points grows the **spendable balance** (shown at the top of the card). The LEGO bar only grows when the child taps a deposit button for that specific reward.
+
+### How do jackpots work with Pool Mode?
+Jackpots are **always pool-mode** (enabling **Is Jackpot** hides the separate Pool toggle). Each assigned child has their own deposit buttons; the combined jackpot pool fills as children contribute. Any assigned child can tap Redeem when it's full; on approval each contributing child loses only their own share. This is how a goal no single child could afford alone gets reached together — combining everyone's points.
+
+### The Claim button on my Rewards Card is missing or won't work
+Make sure you're on **v4.2.1 or newer**. Earlier versions only showed a claim button when the card had a `child_id` set. As of v4.2.1 the card shows a **child picker** and defaults to the first child when `child_id` is omitted, so claiming works out of the box. For jackpot rewards you'll see pooled **deposit** buttons rather than a single claim button — that's expected (jackpots combine everyone's points).
+
+### The deposit button says "Select a child to deposit" — why?
+The card has no `child_id` set, so TaskMate doesn't know which child is making the deposit. Either set `child_id:` in the card YAML, or use one card per child.
+
+### What are assignment modes?
+Assignment modes control how a chore is distributed among assigned children. `everyone` (default) shows it to all children. `alternating` rotates one child per day. `random` picks a random child each day. `balanced` distributes today's chores evenly so no one child gets overloaded.
+
+### Can I publish chores to a calendar?
+Yes. On each chore, select one or more HA calendar entities in the **Calendar Entities** field. TaskMate creates all-day events for each assigned child, projected ahead by the configured number of days (default 14, up to 90). Configure the projection horizon in Settings.
+
+### What is the claim allowance?
+A grace period (in minutes) after a chore's time window ends during which the child can still complete it. Default: 0 (no grace). Set it on a per-chore basis.
+
+### What is the availability entity on a child?
+An optional HA entity (e.g. `binary_sensor` or `input_boolean`) that indicates whether a child is available. When the entity is not in a recognised "available" state, chores with **Require Availability** enabled will skip that child in assignment rotation. You can also set **Availability Inverted** to flip the logic, and add an **Unavailability Entity** as a second busy signal.
+
+## Timed tasks
+
+### What are timed tasks?
+Chores where points are earned based on duration rather than a tick-off. Children start, pause, and stop a timer. Points are calculated as `floor(total_seconds / (rate_minutes × 60)) × rate_points`. See [Timed Tasks](Timed-Tasks.md).
+
+### Can I set a daily limit on timed tasks?
+Yes — use the **Daily Cap (minutes)** setting on the chore. When the cap is reached, the timer cannot be started again until the next day. Set to `0` for unlimited.
+
+### What happens if a child forgets to stop the timer?
+Stale sessions from previous days are automatically stopped and submitted at midnight. A completion record is created with the elapsed time up to that point.
+
+## Task groups
+
+### What are task groups?
+Task groups coordinate how rotation-mode chores are assigned together. A **sticky** group assigns all its chores to the same child. A **spread** group assigns each chore to a different child. See [Task Groups](Task-Groups.md).
+
+### Do task groups work with "everyone" mode?
+No — groups only affect chores using `alternating`, `random`, or `balanced` assignment modes. Chores in `everyone` mode are shown to all children regardless of groups.
+
+## Bonus subtasks
+
+### What are bonus subtasks?
+Optional extra-credit tasks embedded within a parent chore. They unlock after the parent chore is completed and award additional points. See [Bonus Subtasks](Bonus-Subtasks.md).
+
+### Do bonus subtasks count toward streaks?
+No — only the parent chore completion affects streak tracking.
+
+## Admin panel
+
+### Where is the admin panel?
+It's in the HA sidebar under **TaskMate**. It opens at `/taskmate-admin` and requires an admin HA user. See [Admin Panel](Admin-Panel.md).
+
+### Is there still a config flow for managing chores and rewards?
+No. The old options/configure flow was retired in v4.0.0 — the admin panel is the only place to manage children, chores, rewards, groups, settings, notifications, badges and templates. A config flow still runs once when you first add the integration, to set the points name and icon.
+
+## Streaks & bonuses
+
+### What's the difference between "reset" and "pause" streak modes?
+- **Reset** (default): miss a day, your streak goes back to 0
+- **Pause**: miss a day, your streak is frozen until you complete again, then resumes
+
+### How do perfect week bonuses work?
+If a child completes at least one chore on every day of a week (Monday to Sunday), they receive the perfect-week bonus the following Monday at midnight. The bonus amount is configurable in Settings.
+
+### What are streak milestones?
+Configurable point bonuses awarded when a streak reaches certain day counts. Default: `3:5, 7:10, 14:20, 30:50, 60:100, 100:200` — meaning +5 points at 3 days, +10 at 7 days, etc. Format is `days:points` CSV.
+
+## Notifications
+
+### Do I get notified when a child does something?
+Yes, by default a `persistent_notification` is created for every pending chore approval and (from v3.0) every pending reward claim.
+
+You can also configure a `notify.*` service — typically a mobile notification integration — in TaskMate settings to also send those notifications to your phone.
+
+## Troubleshooting
+
+### The rewards card shows "Entity not found"
+Make sure the `entity` config points to an existing sensor. The default is `sensor.taskmate_overview` — check Developer Tools → States to confirm it exists.
+
+### My changes don't show up after updating
+Hard-refresh your Lovelace dashboard with `Ctrl/Cmd + Shift + R`. Home Assistant caches frontend assets aggressively.
+
+### Pool allocations aren't deducting from the child's balance
+This was a bug in v3.0.0-beta1 — upgrade to v3.0.0 (stable) or later. An automatic migration adjusts existing allocations on first load.
+
+### What is career score?
+A long-term performance metric: `total_points_earned − total_penalties_received`. It's tracked per child and snapshotted daily for historical trends.
+
+## Related
+
+- [Managing Rewards](Managing-Rewards.md)
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md)
+- [Services](Services.md)
+- [Sensor Attributes](Sensor-Attributes.md)
diff --git a/wiki/Family-Goals.md b/wiki/Family-Goals.md
new file mode 100644
index 00000000..ba3da825
--- /dev/null
+++ b/wiki/Family-Goals.md
@@ -0,0 +1,74 @@
+# Family Goals
+
+A Family Goal is a single shared target the whole family works toward together. Instead of each child chasing their own rewards, everyone's points are added up against one combined target — *"when the family reaches 500 points between us, we have a movie night"*. It is co-operative rather than competitive, and it is **parent-controlled**.
+
+
+
+Where [Pool Mode](Pool-Mode-(Savings-Jars).md) lets a group of children save toward one reward jar, a Family Goal measures **everyone's combined balance** family-wide, with no deposits to make — it simply tracks the total.
+
+Family Goals are **opt-in** and configured in the **TaskMate** panel → **Settings**, in the **Family goal** section of the Admin Panel.
+
+---
+
+## Settings
+
+| Setting | Key | Default | Description |
+|---------|-----|---------|-------------|
+| **Enable family goal** | `family_goal_enabled` | `off` | Master toggle |
+| **Goal name** | `family_goal_name` | *(blank)* | A friendly name, e.g. *Movie night fund* (up to 120 characters) |
+| **Target (combined points)** | `family_goal_target` | `500` | Sum of all children's points needed to reach the goal (1–10,000,000) |
+| **Reward** | `family_goal_reward` | *(blank)* | What the family gets, e.g. *a family movie night* (up to 200 characters) |
+
+---
+
+## Setting it up
+
+1. Open the **Admin Panel** and scroll to the **Family goal** section
+2. Switch **Enable family goal** on
+3. Give it a **Goal name** — this is the headline shown on the card
+4. Set a **Target** — the combined point total to aim for
+5. Describe the **Reward** the family earns when the goal is reached
+
+The progress metric is simply the **sum of every child's current points**. As children earn (and spend) points, the family total moves up and down toward the target.
+
+If you change the **target** or toggle the goal off and on again, the "reached" state resets so the goal can be celebrated afresh.
+
+---
+
+## Reaching the goal
+
+When the combined total first reaches the target, TaskMate fires a one-time **Family goal reached** notification announcing the goal name and its reward. The notification fires **once** per goal — it won't nag every time the total wobbles back above the line. (See [Notifications](Notifications.md) to control where it is delivered.)
+
+A `taskmate_family_goal_reached` event is also fired with the goal name, reward, and target, so you can trigger your own celebration automation.
+
+---
+
+## The Family Goal card
+
+Add the **Family Goal card** to a dashboard to show live progress toward the target — a progress bar, the combined total against the target, the percentage, and the reward. When the goal is reached the card switches to a trophy and a celebration message.
+
+```yaml
+type: custom:taskmate-family-goal-card
+entity: sensor.taskmate_overview
+title: Movie Night Fund
+header_color: "#16a085"
+```
+
+| Option | Required | Description |
+|--------|----------|-------------|
+| `entity` | ✅ | The TaskMate overview sensor (`sensor.taskmate_overview`) |
+| `title` | — | Overrides the heading; defaults to the goal name |
+| `header_color` | — | Accent colour for the icon and progress bar (default `#16a085`) |
+
+If no family goal is enabled, the card shows a quiet "No family goal set" placeholder. The card reads the overview sensor's `family_goal` attribute, which exposes `enabled`, `name`, `target`, `reward`, `progress`, and `achieved`.
+
+See [Dashboard Cards](Dashboard-Cards.md) for the full set of cards.
+
+---
+
+## Related
+
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — per-reward shared savings jars
+- [Dashboard Cards](Dashboard-Cards.md) — adding the Family Goal card
+- [Notifications](Notifications.md) — controlling the goal-reached notification
+- [Sensor Attributes](Sensor-Attributes.md) — the `family_goal` overview attribute
diff --git a/wiki/Getting-Started.md b/wiki/Getting-Started.md
new file mode 100644
index 00000000..1dfa954e
--- /dev/null
+++ b/wiki/Getting-Started.md
@@ -0,0 +1,150 @@
+# Getting Started
+
+This guide walks you through setting up TaskMate for the first time after installation.
+
+
+
+> **Prefer a guided start?** The [Setup Wizard](Setup-Wizard.md) opens by itself the first time you open the panel, and sets up children, age-suitable chores and starter rewards in one go.
+
+---
+
+## Step 1 — Add the Integration
+
+1. Go to **Settings** → **Devices & Services**
+2. Click **+ Add Integration**
+3. Search for **TaskMate** and select it
+4. You will be asked to choose:
+ - **Points Currency Name** — what you want to call the points (Stars, Coins, Bucks, Tokens, etc.)
+ - **Points Icon** — the MDI icon used throughout the UI (default: `mdi:star`)
+5. Click **Submit**
+
+> You can change the currency name and icon later in Settings.
+
+---
+
+## Step 2 — Open the TaskMate Panel
+
+After setup, **TaskMate** appears in the Home Assistant sidebar. Everything is
+managed from there.
+
+The panel is organised into three groups:
+
+| Group | Contains |
+|-------|----------|
+| **Today** | Activity (approvals and recent events) and [Insights](Insights.md) |
+| **Manage** | Children, Chores, Rewards, Penalties, Bonuses, Groups, Quests, Challenges, Badges, Templates |
+| **System** | Notifications, Audit, Settings |
+
+> Older versions of TaskMate were configured through
+> **Settings → Devices & Services → TaskMate → Configure**. That menu is gone;
+> the panel replaced it.
+
+---
+
+## Step 3 — Add Your Children
+
+1. Go to **Children**
+2. Click **+ Add child**
+3. Enter the child's name and pick an avatar
+4. Save
+
+Repeat for each child. Each child gets their own:
+- Points balance
+- Streak counter
+- Chore completion history
+- Custom chore order
+
+---
+
+## Step 4 — Create Some Chores
+
+1. Go to **Chores**
+2. Click **+ Add chore** (or **Bulk add** to create several at once, or
+ **Create from template** to start from a built-in pack)
+3. Fill in the fields:
+ - **Name** — e.g. "Make Bed"
+ - **Points** — how many points completing this chore earns
+ - **Time of day** — Morning, Afternoon, Evening, Night, or Anytime
+ - **Schedule** — specific days, a recurring interval, or a one-shot task
+ - **Requires approval** — whether a parent must approve before points are awarded
+4. Save
+
+Further options — dependencies, weather conditions, visibility, bonus sub-tasks,
+scheduled changes — live under the **Advanced** sections of the same dialog.
+
+> **Tip:** Start with 3–5 chores. You can add more any time.
+
+See [Chores](Chores.md) for a full explanation of every field.
+
+---
+
+## Step 5 — Create a Reward
+
+1. Go to **Rewards**
+2. Click **+ Add reward**
+3. Enter a name and choose an icon
+4. Set the **points cost**
+5. Optionally make it a **jackpot** so assigned children pool their points
+ toward a shared goal
+6. Save
+
+See [Rewards](Rewards.md) for jackpot rewards, spending caps and the claim
+approval flow.
+
+---
+
+## Step 6 — Add Cards to Your Dashboard
+
+1. Edit your Lovelace dashboard
+2. Click **+ Add Card**
+3. Search for "taskmate" — you'll see all 21 cards listed
+4. Add the **Child Card** for your child's view — configure it with:
+ - Entity: `sensor.taskmate_overview`
+ - Child: select the child
+5. Add the **Parent Dashboard Card** for the parent view
+
+> **Tip:** Create two separate dashboards — one for kids (Child Card + Rewards Card) and one for parents (Parent Dashboard Card).
+
+See [Dashboard Cards](Dashboard-Cards.md) for full configuration options for all cards.
+
+---
+
+## Step 7 — Test It
+
+1. Open the child card on your dashboard
+2. Tap a chore to complete it
+3. If the chore requires approval, go to the parent dashboard and approve it
+4. Watch the points balance update
+
+---
+
+## Finding IDs
+
+Many card options and service calls require a `child_id` or `reward_id`. The easiest way to find these:
+
+1. Go to **Developer Tools** → **States**
+2. Find `sensor.taskmate_overview`
+3. Expand the entity attributes
+4. Look in the `children` array for `id` values
+5. Look in the `rewards` array for reward IDs
+
+IDs are 8-character alphanumeric strings, e.g. `a8c8376a`.
+
+---
+
+## Recommended Dashboard Layout
+
+### Kids' Dashboard (Sections View)
+| Section | Cards |
+|---------|-------|
+| Chores | Child Card (Morning), Child Card (Afternoon), Child Card (Evening) |
+| Rewards & Progress | Rewards Card, Streak Card |
+
+### Parents' Dashboard (Sections View)
+| Section | Cards |
+|---------|-------|
+| At a Glance | Overview Card, Parent Dashboard Card |
+| Points Management | Points Card, Approvals Card |
+| History & Stats | Activity Card, Weekly Card, Leaderboard Card |
+
+> **Tip:** Use Section view for both dashboards — it groups related cards visually and handles responsive layout automatically.
diff --git a/wiki/Gifting-Points.md b/wiki/Gifting-Points.md
new file mode 100644
index 00000000..c3409c0a
--- /dev/null
+++ b/wiki/Gifting-Points.md
@@ -0,0 +1,64 @@
+# Gifting Points
+
+Gifting lets one child hand some of their saved points to a sibling — a birthday treat, a thank-you, or chipping in toward a shared goal. It is **parent-controlled**: gifts are made by an admin from the Admin Panel, not by the children themselves.
+
+
+
+Configured and used from the **Children** tab of the Admin Panel (the **Gift points** button appears once you have at least two children).
+
+---
+
+## How it works
+
+1. Open the **Children** tab and click **Gift points**
+2. Pick the **From** child (the sender) and the **To** child (the recipient)
+3. Enter an **Amount** and send the gift
+
+The amount moves from the sender's spendable balance to the recipient's spendable balance immediately. Both children see an entry in their activity feed.
+
+### What a gift does and doesn't touch
+
+- **Spendable balance only.** The sender's balance drops and the recipient's rises by the same amount.
+- **Earned totals and career score are untouched on both sides.** The recipient didn't earn the points, so their `total_points_earned` and career score do not change — gifting cannot be used to climb the leaderboard or unlock level/XP rewards.
+- Both sides are logged: the sender gets a `Gift to ` transaction, the recipient a `Gift from ` transaction.
+
+---
+
+## Limits and rules
+
+| Rule | Behaviour |
+|------|-----------|
+| **Minimum amount** | 1 point (must be positive) |
+| **Maximum amount** | 10,000 per gift |
+| **Same child** | A child cannot gift to themselves — the gift is rejected |
+| **Insufficient balance** | If the sender doesn't have enough spendable points, the gift is rejected with an error |
+
+---
+
+## Service
+
+Gifting is also available as a service for automations. It is **admin-gated**.
+
+```yaml
+service: taskmate.gift_points
+data:
+ from_child_id:
+ to_child_id:
+ points: 25
+```
+
+| Parameter | Required | Description |
+|-----------|----------|-------------|
+| `from_child_id` | ✅ | ID of the child sending points |
+| `to_child_id` | ✅ | ID of the child receiving points |
+| `points` | ✅ | Amount to transfer (1–10000) |
+
+On success a `taskmate_points_gifted` event is fired with `from_child_id`, `from_child_name`, `to_child_id`, `to_child_name`, `points`, and `timestamp` — useful for triggering a notification or celebration automation.
+
+---
+
+## Related
+
+- [Points Economy](Points-Economy.md) — automatic point mechanics
+- [Children](Children.md) — managing children and their balances
+- [Services](Services.md) — full service-call reference
diff --git a/wiki/Guest-Child-Profiles.md b/wiki/Guest-Child-Profiles.md
new file mode 100644
index 00000000..3961f105
--- /dev/null
+++ b/wiki/Guest-Child-Profiles.md
@@ -0,0 +1,43 @@
+# Guest Child Profiles
+
+A visiting cousin gets a temporary child profile that expires on its own and stays out of the family leaderboard.
+
+
+
+Set **Guest** and an end date on a child (`is_guest`, `guest_expires_on`).
+
+---
+
+## Key Points
+
+- **Guests don't compete.** They're excluded from the [leaderboard](Leaderboard-Seasons.md) — a cousin here for a week shouldn't win the month, and their leaving shouldn't read as a loss for everyone else.
+- **No end date means no expiry.** You may not know how long the visit is, and silently archiving someone mid-stay would be worse than leaving the profile up a bit too long.
+- **Expired guests are archived, not deleted.** The visit's completions stay in history, and next summer the same guest can be reactivated rather than rebuilt from scratch.
+- **Promoting a guest to a family member** clears the end date and un-archives them. Someone who moves in shouldn't stay invisible.
+
+---
+
+## How Archiving Works
+
+Archiving reuses the existing availability plumbing, so every chore and streak path already treats an archived guest as away — the same way [vacation mode](Vacation-Mode.md) does. There is no separate code path that could disagree with the rest of the integration about whether a child is present.
+
+Archiving fires `taskmate_guest_archived`.
+
+---
+
+## A Typical Visit
+
+1. Add the child, tick **Guest**, set the end date to the day they go home.
+2. Assign them a couple of chores — they earn points like anyone else.
+3. They stay off the leaderboard throughout.
+4. On the end date they are archived automatically. Their history remains.
+5. Next visit, reactivate the same profile.
+
+---
+
+## Related
+
+- [Children](Children.md) — adding and managing children
+- [Leaderboard Seasons](Leaderboard-Seasons.md) — which guests are excluded from
+- [Vacation Mode](Vacation-Mode.md) — the same availability mechanism, for family members
+- [Automations](Automations.md) — every TaskMate bus event
diff --git a/wiki/Help-Requests.md b/wiki/Help-Requests.md
new file mode 100644
index 00000000..722b378b
--- /dev/null
+++ b/wiki/Help-Requests.md
@@ -0,0 +1,71 @@
+# Help Requests
+
+Sometimes a child can't finish a job: the bin is too heavy, the hoover won't start, they can't reach the shelf. Rather than giving up or leaving it, they tap **I'm stuck** on the chore. You get a push on your phone, and their card tells them help is on its way. Nothing is completed or skipped; the chore just waits until you've helped.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## On the Child Card
+
+Every chore the child still has to do today shows a small **🙋 I'm stuck** button. Tapping it:
+
+1. sends the parents the *Asked for help* notification: "🙋 Vaiha needs help with 'Empty the dishwasher'"
+2. changes the button to **🙋 Help is on its way**
+
+The request stays open until a parent marks it answered, or for two hours, whichever comes first. A second tap on the same chore within ten minutes doesn't buzz you again.
+
+The button is hidden on chores that are already done, and on cards in [pre-reader mode](Pre-Reader-Mode.md). To hide it on a card:
+
+```yaml
+type: custom:taskmate-child-card
+entity: sensor.taskmate_overview
+child_id: 8e16ad66b23f404e
+show_help_button: false
+```
+
+In the editor it's **Show the "I'm stuck" button**.
+
+---
+
+## Answering on the Today Page
+
+Open requests appear at the top of the panel's **Today** page under **Asked for help**, with the child, the chore, any message and how long ago they asked.
+
+
+
+Tap **On my way** to mark the request answered, so the child's card stops saying help is on its way.
+
+---
+
+## The Notification
+
+**Asked for help** is **on by default**, for new installs and upgrades alike: a help button that reaches nobody is worse than no button. It goes to parents; change who gets it, or switch it off, under **Notifications**.
+
+> 🙋 Vaiha needs help with 'Take the bins out' — “The bin is too heavy”
+
+The message part only appears when the request includes one (the `message` field of the service; the card button sends none).
+
+The notification fires the `taskmate_help_requested` event whether or not it's switched on, with `child_id`, `child_name`, `chore_id`, `chore_name`, `message` and `request_id`. On the child's [event entity](Event-Entities.md) it shows as **Help requested**, which makes it easy to, say, flash a light in the kitchen when someone's stuck.
+
+---
+
+## Services
+
+| Service | Fields | Description |
+|---------|--------|-------------|
+| `taskmate.request_help` | `child_id`, `chore_id`, `message` (optional, up to 120 characters) | Ask for help with a chore. Refused with "Help is already on its way" if the same child asked about the same chore in the last ten minutes |
+| `taskmate.answer_help` | `request_id` | Mark a request answered |
+
+Each child's entry in `sensor.taskmate_overview`'s `children` attribute lists the chores with an open request under `help`.
+
+---
+
+## Related
+
+- [Mood Check-In](Mood-Check-In.md) — how the day felt
+- [Notifications](Notifications.md) — routing the Asked for help push
+- [Admin Panel](Admin-Panel.md) — the Today page
+- [Event Entities](Event-Entities.md) — automating on a help request
diff --git a/wiki/Insights.md b/wiki/Insights.md
new file mode 100644
index 00000000..702a3cc3
--- /dev/null
+++ b/wiki/Insights.md
@@ -0,0 +1,103 @@
+# Insights
+
+**TaskMate panel → Insights.** Five reports that answer the questions the raw numbers don't.
+
+| Report | Question it answers |
+|--------|--------------------|
+| [Fairness](#fairness--who-is-actually-doing-the-work) | Am I dumping everything on the eldest? |
+| [Friction](#friction--what-isnt-working) | Which chores are quietly never getting done? |
+| [Week ahead](#week-ahead--whats-coming-up) | What points are actually available in the next seven days? |
+| [Health](#health--is-anything-broken) | Is anything misconfigured? |
+| [Moods](#moods--how-the-days-felt) | *(v7.0.0)* How have the children's days felt lately? |
+
+All of them are computed **on demand and never cached**. A stale report is worse than a slow one.
+
+---
+
+## Fairness — who is actually doing the work
+
+
+
+For a chosen window (7, 14 or 30 days) it shows each child's completed chores, points earned, share of the family total, and how many distinct days they were active — with a marker showing where an even split would sit.
+
+**Judged on chore count, not points.** A pricier chore shouldn't be able to hide an uneven split. Points are shown alongside because the two can genuinely disagree: three quick jobs versus one hard one is balanced by points and lopsided by count, and only you can say which you meant.
+
+A child is flagged as **doing more** or **doing less** when they are more than **15 percentage points** off an even share — wide enough that normal week-to-week variation doesn't nag, narrow enough to catch a real imbalance.
+
+**Minutes too (v7.0.0).** When chores have [estimated minutes](Estimated-Minutes.md), each child's row also shows the time their approved chores took and their share of it, e.g. "85 min (40% of the time)". A 30-minute job and a 2-minute one are each "one chore", so time is a third view of effort. Only chores with an estimate count towards it, and the line is hidden when none have one.
+
+**Only approved, non-bonus completions count.** Unapproved work isn't yet work you've agreed happened, and bonus sub-tasks hang off a chore that is already counted.
+
+---
+
+## Friction — what isn't working
+
+
+
+The second view judges each **chore** rather than each child: how often it actually gets done versus how often it came up, over 14, 30 or 90 days.
+
+| Verdict | Meaning | Suggestion |
+|---------|---------|------------|
+| **Never done** | No completion on record, ever | Retire it |
+| **Stalling** | Done under 20% of the time it came up | Retire if long dead, otherwise raise the points or reassign |
+| **Patchy** | Done 20–60% of the time | Raise the points |
+| **Fine** | Done 60%+ of the time | Leave it alone |
+
+Chores with outstanding mandatory misses show a ⚠ count. The report leads with a **suggestion** rather than just a diagnosis — a stalling chore that already pays well doesn't need more points, it needs a different child.
+
+**What it can't tell you.** TaskMate deletes a completion when you reject it, and removes a mandatory miss once you resolve it, so neither rejection counts nor historical miss counts exist to be reported. The report says so rather than quietly omitting them. Expected counts are approximate — they don't replay rotation, dependencies, weather or vacations.
+
+---
+
+## Week ahead — what's coming up
+
+
+
+The third view projects the next 7, 14 or 28 days from each chore's schedule: how many chores and points are heading each child's way, what balance they'd reach, and a day-by-day grid.
+
+Rotation is projected using the **same daily-assignment computation the integration itself uses**, so alternating, random and balanced picks match what will really happen rather than an independent guess that could drift.
+
+**It's a ceiling, not a forecast.** A chore open to everyone is counted for *each* eligible child, because the schedule cannot know who will get there first. Weather, dependencies and availability aren't projected either — they depend on the day. Points that aren't assigned to anyone are called out separately.
+
+---
+
+## Health — is anything broken?
+
+
+
+The fourth view checks the setup itself and reports storage size and entity counts.
+
+| Check | Severity |
+|-------|----------|
+| A chore depends on a chore that no longer exists, so it can never unlock | **Error** |
+| A chore or reward is assigned to a deleted child | Warning |
+| A chore references a visibility or weather entity that doesn't exist | Warning |
+| A reward unlocks an entity no longer on the allowlist, so nothing will happen | Warning |
+| A child has no chores; completion records for deleted chores; a very large history | Note |
+
+Every issue carries a plain sentence and a **Show me** button that jumps to where it lives — a diagnostic that only says "3 problems" isn't one you can act on.
+
+**Notes alone still count as healthy.**
+
+---
+
+## Moods — how the days felt
+
+> **New in v7.0.0**
+
+Once a child's chores are done for the day, the child card asks "How was your day?" with five faces: great, good, OK, sad and cross. **Insights → Moods** lays out each child's answers day by day, with how many days they logged and how many were tough (sad or cross). A run of tough days is worth a chat.
+
+Moods are kept for 90 days. A sad or cross day can also send you a gentle push (the **Tough day** notification, off by default). See [Mood Check-In](Mood-Check-In.md).
+
+---
+
+## Related
+
+- [Admin Panel](Admin-Panel.md) — where Insights lives
+- [Recaps](Recaps.md) — a Wrapped-style story of each child's week, month or year
+- [Chores](Chores.md) — fixing what friction finds
+- [Chore Dependencies](Chore-Dependencies.md) — the broken-dependency error
+- [Timed Unlock Rewards](Timed-Unlock-Rewards.md) — the allowlist warning
+- [Mandatory Chores](Mandatory-Chores.md) — the ⚠ miss counts
+- [Mood Check-In](Mood-Check-In.md) — the end-of-day check-in behind the Moods view
+- [Estimated Minutes](Estimated-Minutes.md) — the minutes in the fairness report
diff --git a/wiki/Installation.md b/wiki/Installation.md
new file mode 100644
index 00000000..7b6a52e0
--- /dev/null
+++ b/wiki/Installation.md
@@ -0,0 +1,138 @@
+# Installation
+
+## Via HACS (Recommended)
+
+
+
+TaskMate is a **default HACS integration** — no custom repository is needed:
+
+1. Open **HACS** in your Home Assistant sidebar
+2. Search for **TaskMate**
+3. Click **Download**
+4. **Restart Home Assistant**
+
+
+Installing as a custom repository (legacy)
+
+TaskMate was accepted into the HACS default list, so this is no longer required.
+It is kept here only for reference — existing custom-repository installs keep
+working and keep receiving releases.
+
+1. **HACS** → ⋮ menu → **Custom repositories**
+2. Enter `https://github.com/tempus2016/taskmate`
+3. Set category to **Integration** → **Add**
+
+
+
+---
+
+## Manual Installation
+
+1. Download the [latest release](https://github.com/tempus2016/taskmate/releases/latest)
+2. Extract the archive
+3. Copy the `taskmate` folder to `/config/custom_components/taskmate/`
+
+Your file structure should look like:
+```
+config/
+└── custom_components/
+ └── taskmate/
+ ├── __init__.py
+ ├── coordinator.py
+ ├── manifest.json
+ ├── sensor.py
+ ├── www/
+ │ ├── taskmate-child-card.js
+ │ └── ... (all 21 card files)
+ └── ...
+```
+
+4. **Restart Home Assistant**
+
+---
+
+## After Installation
+
+After restarting, add the integration:
+
+1. Go to **Settings** → **Devices & Services**
+2. Click **Add Integration**
+3. Search for **TaskMate**
+4. Follow the setup wizard — see [Getting Started](Getting-Started.md)
+
+---
+
+## Lovelace Resources
+
+TaskMate automatically registers all 21 Lovelace card resources when it loads. You do **not** need to add them manually in storage mode.
+
+On every restart, TaskMate will:
+- Add any missing card resources
+- Update the cache-busting version string (`?v=x.x.x`) so browsers fetch fresh JS
+
+### YAML Mode Users
+
+If your Lovelace is in YAML mode, add these resources to your `configuration.yaml`:
+
+```yaml
+lovelace:
+ resources:
+ - url: /taskmate/taskmate-child-card.js
+ type: module
+ - url: /taskmate/taskmate-rewards-card.js
+ type: module
+ - url: /taskmate/taskmate-approvals-card.js
+ type: module
+ - url: /taskmate/taskmate-points-card.js
+ type: module
+ - url: /taskmate/taskmate-reorder-card.js
+ type: module
+ - url: /taskmate/taskmate-overview-card.js
+ type: module
+ - url: /taskmate/taskmate-activity-card.js
+ type: module
+ - url: /taskmate/taskmate-streak-card.js
+ type: module
+ - url: /taskmate/taskmate-weekly-card.js
+ type: module
+ - url: /taskmate/taskmate-graph-card.js
+ type: module
+ - url: /taskmate/taskmate-reward-progress-card.js
+ type: module
+ - url: /taskmate/taskmate-leaderboard-card.js
+ type: module
+ - url: /taskmate/taskmate-parent-dashboard-card.js
+ type: module
+ - url: /taskmate/taskmate-penalties-card.js
+ type: module
+ - url: /taskmate/taskmate-bonuses-card.js
+ type: module
+ - url: /taskmate/taskmate-points-display-card.js
+ type: module
+ - url: /taskmate/taskmate-calendar-card.js
+ type: module
+ - url: /taskmate/taskmate-routine-card.js
+ type: module
+ - url: /taskmate/taskmate-badges-card.js
+ type: module
+ - url: /taskmate/taskmate-family-goal-card.js
+ type: module
+ - url: /taskmate/taskmate-photo-gallery-card.js
+ type: module
+```
+
+> **Note:** Three global support modules (`taskmate-config-sounds.js`, `taskmate-localize.js`, `taskmate-design.js`) are registered automatically via `add_extra_js_url()` and do not need to be listed as Lovelace resources. `taskmate-attr-resolver.js` is a normal Lovelace resource and is registered with the cards.
+
+---
+
+## Upgrading
+
+### Via HACS
+
+HACS will show a notification when a new version is available. Click **Update** and restart Home Assistant.
+
+### Manual
+
+Replace the contents of `/config/custom_components/taskmate/` with the new release files and restart.
+
+Resource version strings are updated automatically on restart — no manual editing of Lovelace resources is needed.
diff --git a/wiki/Kiosk-Mode.md b/wiki/Kiosk-Mode.md
new file mode 100644
index 00000000..52610eae
--- /dev/null
+++ b/wiki/Kiosk-Mode.md
@@ -0,0 +1,249 @@
+# Kiosk Mode
+
+Turn a spare tablet on the kitchen wall into the family's chore station. The **Kiosk** card shows a picker of your children's faces. A child taps theirs, types a 4-digit PIN if they have one, and sees only their own chores for today with big **Done** buttons, their points, streak and progress towards the next reward. After a spell without a tap, it goes back to the picker, ready for the next child.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## How It Works
+
+1. **Pick a face.** The picker shows each child with today's progress ("3 of 6 done") and their points. A padlock marks a child who needs a PIN.
+2. **Enter the PIN** (only if one is set). The pad submits on the 4th digit. A wrong PIN shakes and asks them to try again.
+3. **Tick things off.** The child sees today's chores with a large **Done** button each, a done/total ring, stars earned today, their streak, and how close they are to the cheapest reward they can't afford yet.
+4. **Back to the picker.** After the idle timeout (60 seconds by default), straight after the "all done" celebration, or when someone taps **Switch** in the child's header ("Not Mia? Switch").
+
+For the last 10 seconds before it returns, a full-screen **Still there?** countdown gives the child a chance to carry on. Leaving the dashboard also locks the kiosk again.
+
+
+
+
+
+---
+
+## Adding the Card
+
+**Edit dashboard → + Add Card → Custom: TaskMate Kiosk Card**
+
+```yaml
+type: custom:taskmate-kiosk-card
+entity: sensor.taskmate_overview
+title: The Mackinnons
+timeout: 90
+children:
+ - child_id: b803da068e6a4b21
+ require_pin: false
+ - child_id: 8e16ad66b23f404e
+ require_pin: true
+```
+
+The card works best in a **Panel** view, so it fills the screen. The full-screen button in its top bar hides the browser's own chrome. To also hide Home Assistant's sidebar and header on the tablet, pair it with the *kiosk-mode* plugin from HACS.
+
+### Configuration
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `entity` | string | `sensor.taskmate_overview` | The TaskMate overview sensor |
+| `title` | string | `TaskMate` | Shown in the top bar, e.g. your family name |
+| `card_design` | string | global default | `classic`, `playroom`, `console`, `cleanpro`, `accessible` or `graphite`. See [Card Design Styles](Card-Design-Styles.md) |
+| `header_color` | string | `#9b59b6` | Colour of the top bar |
+| `timeout` | number | `60` | Seconds without a tap before it returns to the picker (15–600) |
+| `warn_before_return` | boolean | `true` | Show the full-screen "Still there?" countdown for the last 10 seconds |
+| `show_points` | boolean | `true` | Points and level in the child's view |
+| `show_streak` | boolean | `true` | Streak in the child's view |
+| `show_reward_progress` | boolean | `true` | Progress towards the next reward |
+| `show_picker_progress` | boolean | `true` | "3 of 6 done" under each face on the picker |
+| `play_sounds` | boolean | `true` | *(v6.2.0)* Play the chore's completion sound on **Done**, and the undo sound on an undo |
+| `show_confetti` | boolean | `true` | *(v6.2.0)* Confetti over the card on **Done** |
+| `show_completion_popup` | boolean | `true` | *(v6.2.0)* The "AWESOME! You did it!" popup with the points earned |
+| `default_sound` | string | `coin` | *(v6.2.0)* Sound for chores without their own. YAML only, same as the child card |
+| `undo_sound` | string | `undo` | *(v6.2.0)* Sound played when a child undoes a chore. YAML only, same as the child card |
+| `show_bounties` | boolean | `false` | *(v6.3.0)* A **Bounty Board** section in the child's view, where they can claim and finish bounties. See [Bounties](#bounties) |
+| `completed_mode` | string | `show` | *(v7.0.0)* `show` keeps done and waiting chores in the list with their Undo button; `hide` drops them. See [Less clutter](#less-clutter) |
+| `elapsed_time_mode` | string | `show` | *(v7.0.0)* What happens to a time-of-day chore once its part of the day has passed: `show`, `dim` or `hide`. See [Less clutter](#less-clutter) |
+| `ambient_mode` | string | `off` | *(v7.0.0)* What the picker turns into when nobody's using it: `off`, `progress` (the family's day) or `photos` (a slideshow of chore photos). See [Ambient mode](#ambient-mode) |
+| `ambient_after` | number | `120` | *(v7.0.0)* Seconds untouched before ambient mode starts (30–1800) |
+| `show_raffle_draws` | boolean | `true` | *(v7.0.0)* Spin the names and land on the winner when a [raffle](Raffles.md) is drawn. See [Raffle draws](#raffle-draws) |
+| `children` | list | all children | Which children appear on the picker, in order. Each entry is `child_id` plus an optional `require_pin` (default `true`) |
+
+Leave `children` out and every child is shown (guest profiles excepted), with a PIN asked for wherever one is set. The visual editor lists each child with a tick box to show or hide them, up/down arrows to set the order, and a **Require PIN** switch. That switch is greyed out ("No PIN set — goes straight in") until you give the child a PIN.
+
+---
+
+## Celebrations
+
+> **New in v6.2.0**
+
+Tapping **Done** on the kiosk gets the same reward as on the [child card](Dashboard-Cards.md#child-card):
+
+- **Sound.** The chore's own [completion sound](Completion-Sounds.md), built-in or uploaded. Chores without one play `default_sound` (a coin, unless you change it).
+- **Confetti** over the card.
+- **A popup**: "AWESOME! You did it!" with the points earned. It closes by itself after 2.5 seconds, or on a tap. If that chore was the child's last one, the "all done" celebration takes over instead.
+- **Undo** plays the undo sound, but only once the undo has actually gone through.
+
+Nothing celebrates if the tick doesn't go through. On a device set to reduce motion, there is no confetti and the popup appears without animating.
+
+Each of the three can be switched off in the card's visual editor (**Sounds**, **Confetti**, **Celebration popup**) or in YAML. See [Configuration](#configuration).
+
+---
+
+## Bounties
+
+> **New in v6.3.0**
+
+Switch on **Bounty Board** in the card's visual editor (or `show_bounties: true` in YAML) and the [bounty board](Bounty-Board.md) appears in each child's view, under today's chores.
+
+
+
+- **Claim.** A child can claim an open bounty they're eligible for. A confirm tells them how long they'll have to finish it. While they hold a claim, the other Claim buttons are greyed out ("Finish your bounty first").
+- **Done!** sends the job to your approval queue, with the completion sound, confetti and a "Nice work!" note.
+- **Photo bounties.** For a bounty that needs [photo proof](Photo-Proof.md), Done opens "Show us the finished job". The child takes the photo on the tablet and it's attached to the completion. The child chooses the camera, because a wall-mounted tablet's rear camera usually faces the wall.
+- **Give back** returns a claimed bounty to the board. **Undo** takes back a finished one within the [child undo window](Child-Undo-Window.md).
+- **Siblings.** A bounty a sibling has claimed shows greyed out ("Malia is on it", with the time until it's back on the board). Bounties the child can't claim, and siblings' finished ones, are hidden.
+
+Bounties don't count towards the done/total ring, so the "all done" celebration still happens when today's chores are finished. While the camera is open the idle countdown pauses for up to 2 minutes. A photo that arrives after the kiosk has locked still counts for the child who took it.
+
+---
+
+## Less clutter
+
+> **New in v7.0.0**
+
+Two options keep a child's list short. Both are in the card's visual editor (**Completed chores** and **Missed time-of-day chores**) and default to showing everything, as before.
+
+**Completed chores** (`completed_mode`)
+
+| Value | What the child sees |
+|-------|---------------------|
+| `show` | **Default.** Done chores stay in the list with their **Undo** button |
+| `hide` | Done chores, and chores waiting for a grown-up, drop out of the list |
+
+Hidden chores still count towards the "3 of 6 done" ring and the "all done" celebration. They just can't be undone from the kiosk; a parent can undo them as usual.
+
+**Missed time-of-day chores** (`elapsed_time_mode`)
+
+A morning, afternoon, evening or night chore that wasn't done once that part of the day is over. Anytime chores are never missed, and a chore still inside its claim allowance after the period ends stays live. The same rule the [child card](Dashboard-Cards.md#child-card) uses.
+
+| Value | What the child sees |
+|-------|---------------------|
+| `show` | **Default.** The chore stays in the list and can still be ticked off |
+| `dim` | Greyed out with a **Missed** label. It can't be ticked off |
+| `hide` | Not shown |
+
+A dimmed or hidden missed chore leaves the day's total, so a child can still reach "all done".
+
+```yaml
+type: custom:taskmate-kiosk-card
+entity: sensor.taskmate_overview
+completed_mode: hide
+elapsed_time_mode: dim
+```
+
+---
+
+## Ambient mode
+
+> **New in v7.0.0**
+
+A wall tablet spends most of the day with nobody touching it. With ambient mode on, the picker changes after `ambient_after` seconds untouched (two minutes by default):
+
+- **`progress`** — a large clock and date, every child's face with a ring showing how much of today is done and their points, and any open [raffles](Raffles.md) with their prize and how many tickets are in.
+- **`photos`** — a slideshow of recent chore [photos](Photo-Proof.md), a new one every 8 seconds, captioned with the time, the child and the chore. With no photos to show, it falls back to the family's day.
+
+The first tap only wakes the tablet back to the picker, so a child brushing past doesn't open anyone's screen. Pick **When nobody's using it** in the card's visual editor, or in YAML:
+
+```yaml
+type: custom:taskmate-kiosk-card
+entity: sensor.taskmate_overview
+ambient_mode: progress
+ambient_after: 300
+```
+
+---
+
+## Offline taps
+
+> **New in v7.0.0**
+
+If the tablet loses its connection to Home Assistant (a wobbly Wi-Fi extender, Home Assistant restarting), the top bar says **No connection** and a **Done** still works. The chore is marked **Waiting to send**, the top bar counts how many are waiting, and they are sent in order as soon as the connection is back.
+
+- A chore that is refused when it finally arrives (a parent already did it, it's no longer due) is dropped, and the kiosk says so.
+- Waiting taps are kept by the open page, not saved to the tablet. Reloading the page while it's offline loses them.
+- Only plain **Done** taps are kept. Undo, bounties and anything else need the connection.
+
+---
+
+## Raffle draws
+
+> **New in v7.0.0**
+
+When a [raffle](Raffles.md) is drawn, the kiosk takes over the screen, spins through the names of the children who bought tickets, slows down and lands on the winner, with the prize. Tap to close it. Each draw is shown once, and only for a draw in the last 15 minutes, so a tablet that was switched off doesn't replay old results.
+
+Turn it off with **Show raffle draws** in the card's visual editor, or `show_raffle_draws: false`.
+
+---
+
+## Setting a PIN
+
+**TaskMate panel → Children → edit a child → Kiosk PIN**
+
+
+
+Type four digits and save. Leave the field blank to keep the current PIN, or turn on **Remove the kiosk PIN** to clear it.
+
+**What the PIN is for.** It keeps siblings out of each other's screen on a shared tablet. It is not an account: every tap still goes through the tablet's Home Assistant login, so what the tablet may do for each child is decided by that login and each child's [linked account](Children.md#child-fields), not by the PIN. Five wrong tries lock the pad for that child, longer each time; the lock is per device, so a wrong PIN typed on a phone elsewhere can't lock the tablet.
+
+- **PINs never go in the card's YAML.** They are stored hashed on the server, so they can't be read back, not even by you. If a child forgets theirs, just set a new one.
+- **Five wrong tries lock the pad.** The first lock lasts 30 seconds and each one after doubles, up to 15 minutes. A correct PIN clears the count.
+- A PIN only decides which sibling is holding the tablet. It is not a permission and unlocks nothing else.
+
+---
+
+## What Kiosk Mode Deliberately Leaves Out
+
+The kiosk is for children. There is no option to add any of these:
+
+- **No parent controls.** No approve or reject, no completing on a child's behalf, no points adjustments, no settings.
+- **No reward claiming.** Children see how close they are, but claim on their own device or ask a grown-up.
+
+Some chores need more than a tap, so they are shown greyed out under **Do these on your phone**:
+
+| Chore type | Why |
+|------------|-----|
+| [Photo proof](Photo-Proof.md) | Needs a camera |
+| [Timed tasks](Timed-Tasks.md) | Needs a running timer |
+| [Open-ended chores](Open-Ended-Chores.md) | Needs a description |
+| [Quantity chores](Quantity-Chores.md) | Needs a number ("how many pages?") |
+
+These don't count against "all done", so a child with one of them still gets the celebration.
+
+Chores that need approval show **A grown-up will check** and change to **Waiting for a grown-up** once ticked. A [teamwork chore](Teamwork-Chores.md) shows **Waiting for your team** after the child joins. If the [child undo window](Child-Undo-Window.md) is switched on, a child can take back a mistaken tap from the kiosk too.
+
+---
+
+## Linked Accounts
+
+Ticking a chore from the kiosk goes through exactly the same checks as ticking it anywhere else, using the tablet's Home Assistant account:
+
+| Setup | What the kiosk can do |
+|-------|-----------------------|
+| Children not linked to any account (the usual family set-up) | Tick chores for every child |
+| A child linked to their own account | Can't tick that child's chores unless the tablet is signed in as an admin |
+| **Require a linked account per child** switched on | Can only tick chores if the tablet's account is a TaskMate parent or an admin |
+
+When the kiosk isn't allowed to act for a child, their face shows **Ask a grown-up**, and tapping it explains why. It never shows buttons that would fail. See [Parent Access](Parent-Access.md) for linking accounts.
+
+---
+
+## Related
+
+- [Children](Children.md) — where kiosk PINs are set
+- [Routine Mode](Routine-Mode.md) — a guided, one-chore-at-a-time view for a single child
+- [Card Design Styles](Card-Design-Styles.md) — the six designs the kiosk follows
+- [Celebrations](Celebrations.md) — on-screen celebrations and the celebration event
+- [Bounty Board](Bounty-Board.md) — posting bounties and the rules for claiming them
+- [Raffles](Raffles.md) — setting up the raffles the kiosk shows and draws
+- [Ready-Made Dashboards](Ready-Made-Dashboards.md) — a wall tablet dashboard with the kiosk, built for you
+- [Parent Access](Parent-Access.md) — linked accounts and parent permissions
diff --git a/wiki/Leaderboard-Seasons.md b/wiki/Leaderboard-Seasons.md
new file mode 100644
index 00000000..1e5005ca
--- /dev/null
+++ b/wiki/Leaderboard-Seasons.md
@@ -0,0 +1,65 @@
+# Leaderboard Seasons
+
+Leaderboard Seasons turn the leaderboard into a fresh monthly contest. Each child builds up **season points** over the current calendar month; on the 1st of the next month the season finalizes, a champion is recorded, and everyone's season total resets to zero. It is a gentle way to keep competition motivating without letting one child run away with it forever.
+
+
+
+---
+
+## Why Seasons?
+
+A plain all-time leaderboard rewards whoever started first or earns the most overall. In a household with siblings of different ages, that often means the same child sits at the top month after month — and the others stop trying.
+
+Seasons fix that. Because totals reset on the 1st of every month, **everyone gets a fresh shot each month**. A younger sibling who has a great few weeks can win this month's season even if they're behind on lifetime points, and last month's winner starts level with everyone else. The all-time and career rankings are still there if you want them — seasons just sit alongside as a recurring, winnable contest.
+
+---
+
+## How Season Points Are Earned
+
+Season points accumulate from **positive point gains only** during the current calendar month — approved chores, bonuses, and other awards all count. Penalties and other deductions do not pull a child's season score down; the season total only ever goes up within the month.
+
+Each child's running total for the month is exposed on the **Overview sensor** (`sensor.taskmate_overview`) as a per-child `season_points` value, and the current month is published as the `season_month` attribute (in `YYYY-MM` form).
+
+---
+
+## How Champions Are Recorded
+
+When the calendar month rolls over, TaskMate finalizes the season automatically:
+
+- The child with the most season points for the finished month is recorded as that month's **champion**.
+- The champion is appended to a `season_champions` history (also on the Overview sensor), so past winners are kept.
+- Every child's `season_points` total resets to zero for the new month.
+- A **`season_champion`** notification announces the winner — for example *"🏆 Maya won the 2026-05 leaderboard with 320 Stars!"*. See [Notifications](Notifications.md) for how to route TaskMate notifications.
+
+If no child earned any points during the month, no champion is recorded for that month.
+
+---
+
+## Showing Seasons on the Leaderboard Card
+
+The [Leaderboard Card](Dashboard-Cards.md) can rank children by their season points. Set `sort_by: "season"`:
+
+```yaml
+type: custom:taskmate-leaderboard-card
+entity: sensor.taskmate_overview
+sort_by: season # points | streak | weekly | career | season
+header_color: "#b7950b"
+```
+
+`sort_by` can also be set from the card's visual editor via the **Rank by** dropdown.
+
+When `sort_by: "season"` is active, children are ordered by their `season_points` for the current month, and the card shows a **champion banner** naming the most recently recorded season champion. Switching back to any other sort mode (`points`, `streak`, `weekly`, `career`) leaves the season tracking untouched — it keeps running in the background regardless of how the card is sorted.
+
+---
+
+## Guests Don't Compete
+
+Children marked as **guests** are left out of the leaderboard entirely. A cousin staying for a week shouldn't win the month, and their going home shouldn't read as everyone else suddenly gaining ground.
+
+See [Guest Child Profiles](Guest-Child-Profiles.md).
+
+## Related
+
+- [Dashboard Cards](Dashboard-Cards.md) — the Leaderboard Card and its full config
+- [Achievement Badges](Achievement-Badges.md) — milestone recognition that pairs well with seasons
+- [Points Economy](Points-Economy.md) — how points are earned and spent
diff --git a/wiki/Levels-and-XP.md b/wiki/Levels-and-XP.md
new file mode 100644
index 00000000..790efbbf
--- /dev/null
+++ b/wiki/Levels-and-XP.md
@@ -0,0 +1,102 @@
+# Levels and XP
+
+Every point a child has ever earned counts as XP, and XP turns into levels. It is a zero-config progression layer that sits on top of the points they already earn — no extra setup needed to get going.
+
+
+
+---
+
+## How It Works
+
+A child's **XP is their lifetime earned points** (`total_points_earned`). This is the cumulative total of everything they've ever earned — chore completions, weekend bonuses, streak milestones, perfect weeks, quest and challenge bonuses, badge point bonuses, manual bonuses, and savings interest. Spending points on rewards does **not** reduce XP, so a child's level only ever goes up.
+
+```
+Lifetime earned points (XP) → Level → Level-up event + celebration
+```
+
+Levels are recalculated automatically every time a child's earned total changes. When the total crosses a level boundary, TaskMate:
+
+1. Updates the child's `level`
+2. Fires a `taskmate_level_up` bus event (one per level crossed)
+3. Sends the optional `level_up` notification (see [Notifications](Notifications.md))
+4. Fires a [celebration](Celebrations.md) — epic at every 5th level, medium otherwise
+
+If a child's earned total ever drops (for example a parent undoes a bonus), the level re-syncs quietly downward with no event.
+
+---
+
+## The Level Curve
+
+Levels use a flat, predictable step: each level costs the same amount of XP.
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **XP per level** (`level_xp_step`) | `100` | Earned points needed to advance one level |
+
+- Level 1 starts at 0 XP
+- With the default step of 100, a child reaches level 2 at 100 lifetime points, level 3 at 200, and so on
+- The formula is `level = (lifetime earned points ÷ XP per level) + 1`
+
+Set the step lower for faster, more frequent level-ups (good for younger kids) or higher to make levels feel more earned.
+
+Configure it in the Admin Panel's **Settings** tab under **XP per level**.
+
+---
+
+## Where Level & XP Appear
+
+### Overview sensor
+
+Each child in the `sensor.taskmate_overview` `children` attribute carries:
+
+| Field | Description |
+|-------|-------------|
+| `level` | Current level |
+| `level_progress` | XP earned toward the next level (0 up to the step size) |
+| `level_target` | XP needed for the next level (the step size) |
+| `total_points_earned` | Lifetime earned points — the raw XP value |
+
+`level_progress` resets to 0 each time a child levels up and counts up to `level_target`.
+
+### Child card
+
+The [child card](Dashboard-Cards.md) shows a **level badge** (e.g. "Lvl 4") beside the child's name, with an **XP progress bar** underneath that fills as they close in on the next level. Hovering the badge shows the exact `progress / target` XP. The badge appears automatically once a child has a level.
+
+---
+
+## Levels Power Other Features
+
+- **[Avatars](Avatars.md)** can be unlocked by reaching a level
+- **Level-up moments** feed the [celebration](Celebrations.md) system and the `level_up` notification
+
+---
+
+## Automation Example
+
+### Announce a level-up on a speaker
+
+```yaml
+alias: Announce level up
+triggers:
+ - trigger: event
+ event_type: taskmate_level_up
+actions:
+ - action: tts.google_translate_say
+ data:
+ entity_id: media_player.kitchen_speaker
+ message: >
+ {{ trigger.event.data.child_name }} reached level
+ {{ trigger.event.data.level }}!
+```
+
+The `taskmate_level_up` event payload includes `child_id`, `child_name`, `level`, and `timestamp`.
+
+---
+
+## Related
+
+- [Avatars](Avatars.md) — unlock avatars by reaching levels
+- [Celebrations](Celebrations.md) — the tiered moments fired on level-up
+- [Dashboard Cards](Dashboard-Cards.md) — child card level badge and XP bar
+- [Notifications](Notifications.md) — the `level_up` notification type
+- [Bonus Points](Bonus-Points.md) — streaks, perfect weeks and other earned points that feed XP
diff --git a/wiki/Localization.md b/wiki/Localization.md
new file mode 100644
index 00000000..335e7102
--- /dev/null
+++ b/wiki/Localization.md
@@ -0,0 +1,103 @@
+# Localization
+
+TaskMate supports multiple languages for both the configuration UI and the Lovelace dashboard cards.
+
+
+
+---
+
+## Supported Languages
+
+| Language | Code | Coverage |
+|----------|------|----------|
+| English (GB) | `en-GB` | Full (default fallback) |
+| English (US) | `en` | Full |
+| Danish | `da` | Full (new in v6.0.0, contributed and reviewed by a native speaker) |
+| French | `fr` | Full |
+| German | `de` | Full |
+| Norwegian Bokmål | `nb` | Full |
+| Norwegian Nynorsk | `nn` | Full |
+| Polish | `pl` | Full (new in v6.1.0, contributed by a native speaker) |
+| Portuguese | `pt` | Full |
+| Portuguese (Brazil) | `pt-BR` | Full |
+
+---
+
+## How It Works
+
+TaskMate automatically uses your Home Assistant language setting. There is no separate language option within TaskMate itself.
+
+### Changing Language
+
+1. Go to your **HA Profile** (click your user icon in the sidebar)
+2. Change **Language** to your preferred language
+3. That's it. Since v6.0.0 the cards and the admin panel switch language (and direction) straight away, with no page reload
+
+**Card titles follow your language (v6.0.0).** The points, approvals, parent dashboard, reorder and rewards cards used to save an English default title ("Manage Points", "Rewards", …) into your dashboard. A title that matches the old English default is now treated as unset, so it shows in your language. Titles you typed yourself are kept exactly as you wrote them.
+
+### What Gets Translated
+
+- **Config flow** — all setup screens, field labels, descriptions, and menu items
+- **Dashboard cards** — all card titles, button labels, status messages, empty states, and tooltips
+- **Admin panel** — all management screens, forms, and labels (v3.6.2+)
+- **Service descriptions** — shown in Developer Tools when browsing services
+- **Push notifications** (v6.2.0) — message text and action buttons. See [Push Notifications](#push-notifications) below
+
+### What Does Not Get Translated
+
+- **Your data** — child names, chore names, reward names, and descriptions are entered by you and displayed as-is
+- **Points currency name** — this is set by you during setup (e.g. "Stars", "Coins") and is not translated
+- **Custom notifications** — the message you write for a [custom notification](Notifications.md#custom-notifications) is sent exactly as written
+
+---
+
+## Push Notifications
+
+> **New in v6.2.0**
+
+TaskMate's push notifications are written in Home Assistant's **server** language, set under **Settings → System → General**. This is separate from the language in your user profile, which the cards and panel follow. Pushes are built on the server and go to several people at once, so they use the household's language.
+
+What's translated:
+
+- Every built-in notification message (approvals, reminders, badges, streaks, auctions, inspections, recaps, celebrations, …)
+- The **Approve** / **Reject** buttons, the reject reply box and its "Reason (optional)" placeholder
+- The "Open the TaskMate panel to approve or reject." hint sent to Telegram, email and other non-mobile backends
+- Auction results, weekly digest and monthly report lines, and lists of names ("Malia, Vaiha und Alex")
+- Month and weekday names in dates, for example in the monthly report, the season champion and auction dates
+- The `message` of the `taskmate_celebration` event, so automations that speak it use your language
+- The sample names in a **Send test** push
+
+A regional language falls back to its base language (Swiss German `de-CH` uses German). If a message has no translation, it goes out in English, so a notification is always readable. A change of language takes effect straight away, with no restart.
+
+Action button identifiers stay the same in every language, so existing automations and notifications already on phones keep working.
+
+---
+
+## Right-to-Left Languages (v6.0.0)
+
+Every TaskMate card and the admin panel lay out **right-to-left** when Home Assistant is set to a right-to-left language such as Arabic, Hebrew, Persian or Urdu, and follow Home Assistant's own direction otherwise. There is nothing to configure.
+
+- Text, spacing, borders and progress bars run from the right; directional icons (chevrons, undo, send) are mirrored
+- Counts and number runs keep their reading order, so "3 / 5", "3-day streak" and "0 of 6 done" read correctly inside right-to-left text
+- Progress rings and the points graph's time axis stay as drawn, so time still runs left to right on the graph
+
+TaskMate doesn't ship Arabic, Hebrew, Persian or Urdu translations yet, so those languages show the layout right-to-left with English wording. The layout is ready for a translation — see below if you'd like to contribute one.
+
+---
+
+## Contributing Translations
+
+Translation files are located in the repository:
+
+- **Config flow**: `custom_components/taskmate/translations/{locale}.json`
+- **Frontend cards**: `custom_components/taskmate/www/locales/{locale}.json`
+
+To add a new language or improve an existing translation, submit a pull request to the [TaskMate repository](https://github.com/tempus2016/taskmate).
+
+---
+
+## Related
+
+- [Installation](Installation.md) — initial setup
+- [Getting Started](Getting-Started.md) — first-time configuration
+- [Notifications](Notifications.md) — notification types and messages
diff --git a/wiki/Logging-Past-Jobs.md b/wiki/Logging-Past-Jobs.md
new file mode 100644
index 00000000..d396e012
--- /dev/null
+++ b/wiki/Logging-Past-Jobs.md
@@ -0,0 +1,77 @@
+# Logging Past Jobs
+
+Sometimes a job gets done but nobody ticks it. The bed was made on Tuesday, but the tablet was flat. **Log a past job** lets you record it afterwards, on the day it was actually done, so your child still gets the points and the week's totals come out right.
+
+
+
+> **New in v6.4.0** — contributed by @cad861
+
+---
+
+## Logging a Job
+
+**TaskMate panel → Children → Log a past job** (on the child's profile card)
+
+1. Pick the **Day it was done**. You can go back up to 7 days; today isn't offered, because today's jobs are ticked the normal way.
+2. The day's jobs appear as a [sticker chart](Sticker-Chart-Card.md). **Tap** each job that was done.
+3. Made a mistake? **Press and hold** a sticker to take it back.
+4. Tap **Done**.
+
+The chart only offers jobs TaskMate would accept for that day, so you won't tap something and then be refused. Jobs already ticked that day show as done.
+
+---
+
+## What a Logged Job Does
+
+| | |
+|---|---|
+| **Approval** | Approved straight away. You are the one logging it, so there is nothing to review, and no photo is asked for. |
+| **Points** | The chore's points (including its [difficulty tier](Difficulty-Tiers.md)), plus the [weekend multiplier](Bonus-Points.md) if the day was a Saturday or Sunday and the [birthday](Birthday-Mode.md) multiplier if it was the child's birthday. Bonuses that depend on a live tap — time of day, speed and [roulette](Chore-Roulette.md) — aren't added. |
+| **Which day it counts for** | The day you picked. It counts towards that day's [daily limit](Chores.md#daily-limit), that week's [weekly target](Weekly-Targets.md) and that week's points totals, such as the sticker chart's week goal. |
+| **Streak** | Left alone. Rewriting the streak for a past day could break the streak your child is on today. |
+| **Everything else** | Counts like any approved job: chores completed, [badges](Achievement-Badges.md), [quest](Quests.md) steps and [challenges](Challenges.md). |
+| **Weekly target bonus** | If the job completes that week's [weekly target](Weekly-Targets.md#weekly-target-bonus), the bonus is paid. Undoing the job takes the bonus back. |
+| **Undo** | Undoing a logged job takes its points back and, like logging it, leaves the streak alone. |
+
+A logged job never makes a recurring chore come round again sooner. If your child has done the chore since, the later one still decides when it's next due.
+
+---
+
+## Jobs That Can't Be Logged
+
+TaskMate refuses a past job, with a message saying why, when:
+
+- the day is more than 7 days ago, or is today or later
+- the chore isn't one of that child's jobs, or is switched off
+- it wasn't due that day (a weekly-target chore can be logged on any day, until that week's target is reached)
+- the day was a [vacation](Vacation-Mode.md) day, or the child's [birthday day off](Birthday-Mode.md) (mandatory chores can still be logged)
+- it was already done as many times as its daily limit allows that day
+- it's a **rotation** or **[teamwork](Teamwork-Chores.md)** chore — whose turn it was, or who made up the team, can't be worked out afterwards
+- it was won at [auction](Chore-Auctions.md) that day
+- it's an [open-ended chore](Open-Ended-Chores.md), which needs the child's description and your price — use the child's card instead
+
+---
+
+## From an Automation or Script
+
+The `taskmate.complete_chore` service takes a `completed_date`:
+
+```yaml
+service: taskmate.complete_chore
+data:
+ chore_id: 8a3b2c1d4e5f6789
+ child_id: ef19c56175c14bd9
+ completed_date: "2026-10-13"
+```
+
+Only a Home Assistant admin or a [TaskMate parent](Parent-Access.md) can use `completed_date`. Automations and scripts are allowed. See [Services](Services.md#taskmatecomplete_chore).
+
+---
+
+## Related
+
+- [Sticker Chart Card](Sticker-Chart-Card.md) — the card the dialog is built from
+- [Chores](Chores.md) — daily limits and approvals
+- [Weekly Targets](Weekly-Targets.md) — how a logged job counts towards the week
+- [Admin Panel](Admin-Panel.md) — where the Children page lives
+- [Services](Services.md) — `complete_chore` and its other options
diff --git a/wiki/Make-It-Right-Penalties.md b/wiki/Make-It-Right-Penalties.md
new file mode 100644
index 00000000..117c7a45
--- /dev/null
+++ b/wiki/Make-It-Right-Penalties.md
@@ -0,0 +1,91 @@
+# Make It Right Penalties
+
+Losing points teaches less than putting right whatever went wrong. A **make-it-right** penalty names a chore that repairs the damage. When you apply the penalty, the child gets an offer: do that chore within a few days and earn back some or all of the points. Left the bike out in the rain? Clean and oil it, and get half the points back.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Setting It Up
+
+Make it right is part of the penalty itself, so set it once and it applies every time that penalty is used.
+
+**TaskMate panel → Penalties → edit a penalty (or + Add penalty) → Make it right**
+
+
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Chore to earn it back** | None — no way back | Any existing chore. Leave it on *None* for an ordinary penalty |
+| **Points back (%)** | `100` | How much of what was taken comes back, 1–100 |
+| **Days to do it** | `1` | 1 = today only, up to 7 |
+
+Every penalty created before v7.0.0 stays an ordinary penalty until you pick a chore for it. These fields are set in the panel; the `add_penalty` and `update_penalty` services don't take them.
+
+---
+
+## What the Child Sees
+
+As soon as the penalty is applied, the child's card shows the offer above their chores:
+
+> 🤝 **Make it right**
+> Do "Clean and oil the bike" by Sunday to earn back 3.
+
+The deadline is the end of the last day: with **Days to do it** set to 2, a penalty on Friday can be made right until the end of Saturday ("by the end of today" when it's today only).
+
+The refund is the chosen percentage of the points actually deducted, rounded, and at least 1. A 6-point penalty at 50% offers 3 back.
+
+### The chore is open to them
+
+While the offer is open, its chore is available to that child **even on days it isn't normally due**, and outside any rotation, so "tidy the mess you made" can be done straight away. Two exceptions keep things fair: a one-off chore that has already been done stays done, and a chore another child won at [auction](Chore-Auctions.md) stays theirs.
+
+---
+
+## Earning It Back
+
+The child does the chore as usual. Only a completion **after** the penalty counts.
+
+- If the chore needs approval, the points come back when you approve it.
+- If it doesn't, they come back straight away.
+
+The refund shows in the child's history as "Made it right: Left the bike out in the rain", and it also comes off their penalty total, so their career score recovers too. The offer is used up.
+
+### If it's undone
+
+Undoing or rejecting the completion that earned the points back takes the refund back again ("Made it right undone: …") and re-opens the offer, so the child can still make it right before the deadline. A child's own undo checks they still have the refunded points in hand first.
+
+If the deadline passes without the chore being done, the offer simply lapses and the penalty stands.
+
+---
+
+## Notification and Event
+
+**Penalty earned back** (off by default; switch it on under **Notifications**) can go to the child, parents or both:
+
+> 🤝 Vaiha made it right with 'Clean and oil the bike' and earned back 3 Points.
+
+It fires the `taskmate_penalty_redeemed` event whether or not the notification is on, with `child_id`, `child_name`, `penalty_name`, `chore_name`, `points` and `points_name`. On the child's [event entity](Event-Entities.md) it shows as **Penalty earned back**.
+
+Open offers are listed under `redemptions` in each child's entry of `sensor.taskmate_overview`'s `children` attribute (chore, penalty, points and the last day).
+
+---
+
+## Ideas
+
+| Penalty | Make it right | Back | Days |
+|---------|---------------|------|------|
+| Left the bike out in the rain | Clean and oil the bike | 50% | 2 |
+| Muddy footprints through the hall | Hoover the hall | 100% | 1 |
+| Slammed the door | Write a sorry note | 100% | 1 |
+| Broke a sibling's model | Help rebuild it | 75% | 7 |
+
+---
+
+## Related
+
+- [Penalties](Penalties.md) — named point deductions
+- [Mandatory Chores](Mandatory-Chores.md) — penalties for missed chores
+- [Child Undo Window](Child-Undo-Window.md)
+- [Notifications](Notifications.md)
diff --git a/wiki/Managing-Rewards.md b/wiki/Managing-Rewards.md
new file mode 100644
index 00000000..d7c4e9fc
--- /dev/null
+++ b/wiki/Managing-Rewards.md
@@ -0,0 +1,92 @@
+# Managing Rewards
+
+Rewards are the things children earn points toward (movie night, an hour of screen time, a LEGO set…). They're created and edited from the Rewards tab of the TaskMate panel.
+
+
+
+## Where to find it
+
+Open the **TaskMate** panel in the Home Assistant sidebar and go to **Rewards**.
+
+The tab lists all existing rewards, with **+ Add reward** to create one.
+
+## Reward form fields
+
+| Field | Required | Description |
+| --- | --- | --- |
+| **Name** | ✅ | Display name shown on cards |
+| **Description** | | Optional longer text shown under the name |
+| **Points cost** | ✅ | Fixed number of points required to earn this reward |
+| **Icon** | | An MDI icon (dropdown picker) |
+| **Assigned to** | | Which children can earn this reward. Leave empty = all children |
+| **Is Jackpot** | | If enabled, pools points from all assigned children toward one shared reward. Jackpots are **always pool-mode**, so the separate Pool Reward toggle is hidden when this is on |
+| **Quantity** | | Limited stock count. Each approved claim decreases it by 1. When it reaches 0 the reward shows as **Sold Out**. Leave empty for unlimited. |
+| **Expiration Date** | | ISO date after which the reward is no longer available. Expired rewards are hidden from claim buttons. Pool allocations for expired rewards are refunded automatically at midnight. Leave empty for no expiry. |
+| **Pool Reward (Savings Jar)** | | If enabled, children deposit points into this reward's dedicated pool rather than spending from their global balance. See below. (Hidden for jackpots, which are always pooled.) |
+
+### Pool Reward toggle (v3.0+)
+
+The **"Pool Reward (Savings Jar)"** switch flips a single reward between two fundamentally different behaviours:
+
+- **Off** (default, wallet mode): Classic behaviour. The child's balance must cover the full cost. Tapping Claim creates a pending claim; approval deducts the cost from the child's balance.
+- **On** (pool mode): The reward shows `[+1] [+5] [+10]` deposit buttons. Children deposit points from their spendable balance; each deposit immediately reduces `child.points` and grows the allocation. When the allocation reaches the reward cost, a Redeem button appears.
+
+You can flip the toggle on an existing reward at any time. If you turn it off after deposits have been made, those points stay allocated until the reward is claimed or deleted — there's no auto-refund.
+
+See [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) for full semantics.
+
+## Editing an existing reward
+
+Click a reward's **✏** button to edit it. The dialog is identical to the add form but pre-filled, with **Save** to persist changes and **Delete** to remove the reward.
+
+### What happens when you delete a reward
+
+- All pending claims for that reward are removed
+- All pool allocations for that reward are cleared (points are **not** refunded to children)
+- The reward disappears from every rewards card
+
+If a reward has active pool allocations and you want to cancel it gracefully, this is currently the escape hatch — delete and recreate.
+
+## Auto-restock (v4.0.0)
+
+Limited-stock rewards can refill on a schedule instead of needing a manual top-up. In the reward's Add/Edit form:
+
+1. Set a **Quantity** so the reward has limited stock
+2. Turn on **Auto-restock**
+3. Set **Restock to** — the number stock is reset to each period
+4. Choose **Restock every**: Day, Week (Mon), or Month (1st)
+
+On the chosen boundary TaskMate resets the reward's **Quantity** back to the Restock-to amount, so a reward that sold out becomes available again. See [Rewards](Rewards.md#auto-restock-v400) for the exact mechanics.
+
+## Per-period spending cap (v4.0.0)
+
+The spending cap is **not** set on individual rewards — it is a family-wide control in the **TaskMate** panel → **Settings**, under **History & streaks**:
+
+1. Turn on **Spending cap**
+2. Set **Cap (pts)** — the maximum points each child may spend on rewards per period (`0` disables it)
+3. Choose the **Period**: weekly (resets Monday) or monthly (resets on the 1st)
+
+Once set, approving a reward claim that would take a child over their cap for the current period is blocked with a "Spending cap reached" error. The claim remains pending, so you can approve it after the period rolls over or reject it. Only approved claims count toward the cap. See [Rewards](Rewards.md#per-period-spending-cap-v400) for the full behaviour.
+
+## Jackpots are always pooled
+
+Enabling **Is Jackpot** automatically puts the reward in pool mode — there's no separate Pool Reward toggle to set (the editor hides it). This is because a jackpot's whole point is combining everyone's points, which only works via the pool. Behaviour:
+
+- The pool total is the sum of all contributing children's allocations
+- Each assigned child has their own `[+1] [+5] [+10]` deposit buttons
+- Any assigned child can tap Redeem when the combined pool fills
+- On approval, each contributing child loses only their own share
+- A goal no single child could afford on their own is reached together
+
+## Tips
+
+- **Price rewards so savings takes days, not weeks.** Short feedback loops keep kids engaged.
+- **Mix pool and wallet rewards** so kids can satisfy an impulse (10pt candy) while working toward a goal (500pt LEGO).
+- **Use jackpots sparingly** — they're powerful for family goals but harder for kids to grok.
+
+## Related
+
+- [Dashboard Cards](Dashboard-Cards.md) — the Rewards card and others
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — the savings-jar feature
+- [Streak Freezes](Streak-Freezes.md) — a Streak freeze reward gives the child a token that saves their streak
+- [Services](Services.md) — programmatic reward operations
diff --git a/wiki/Mandatory-Chores.md b/wiki/Mandatory-Chores.md
new file mode 100644
index 00000000..3cbafd98
--- /dev/null
+++ b/wiki/Mandatory-Chores.md
@@ -0,0 +1,91 @@
+# Mandatory Chores
+
+Mandatory chores are chores a child is expected to do — not optional, not just "nice to have". When a mandatory chore isn't completed in time, TaskMate doesn't silently take points away. Instead it raises a **review item** for the parent, who decides what happens next.
+
+Mandatory is set **per chore** — there is no global on/off switch.
+
+## Marking a chore mandatory
+
+Open the chore editor (**Admin Panel → Chores → Edit chore**). Turn on the **"Mandatory chore"** toggle. A **"Penalty points if missed"** number field appears below it — set the points a parent can choose to deduct if the chore is missed. Leave it at `0` for no penalty option.
+
+
+
+In YAML / storage this is two chore fields:
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `mandatory` | bool | Whether the chore is mandatory |
+| `mandatory_penalty_points` | int | Points a parent may deduct if missed (`0` = no penalty option) |
+
+## How a miss is detected
+
+If a mandatory chore isn't completed before its time-of-day period ends, TaskMate records a per-child **miss** and raises a review item for the parent. **Points are never auto-deducted** — the parent always chooses what to do.
+
+Detection runs at the end of each period. A midnight pass handles **Anytime** chores (which have no period boundary during the day), and a catch-up scan runs after Home Assistant restarts — so a restart across a period boundary won't cause a miss to be skipped.
+
+See [Chore Scheduling](Chore-Scheduling.md) for how time-of-day periods work.
+
+## Escalating a miss
+
+An open miss can also step up its reminders over time so it doesn't sit unnoticed until you review it. The [Reminder Escalation](Reminder-Escalation.md) ladder nudges the child first, reminds them again after a configurable delay, and finally alerts a parent if the chore is still not done. The escalation notifications are off by default — see [Reminder Escalation](Reminder-Escalation.md) to enable and tune them.
+
+## Reviewing a miss
+
+The review item appears on the [Approvals Card](Approvals-Card.md) under a section titled **"Mandatory — needs review"**, at the top of the card.
+
+
+
+Each miss offers three parent actions, each backed by a [service](Services.md):
+
+| Action | Service | Effect |
+| --- | --- | --- |
+| **Apply Penalty** | `taskmate.apply_mandatory_penalty` | Deducts the configured penalty points and clears the review item. The Apply-penalty button only appears when the chore's penalty points are greater than 0. |
+| **Postpone** | `taskmate.postpone_mandatory_chore` | Gives the chore the next period today, rolling to tomorrow after the last period. Repeatable, and applies no penalty. |
+| **Dismiss** | `taskmate.dismiss_mandatory_chore` | Clears the review item with no penalty. |
+
+Every one of these services takes a single parameter:
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| `miss_id` | string | The ID of the mandatory-miss review item |
+
+The penalty deducted by **Apply Penalty** is fixed — see [Penalties](Penalties.md) for how penalties show up in the activity log.
+
+## On the child card
+
+A mandatory chore is shown distinctly on the child card so kids can see at a glance what's non-negotiable: a red left stripe, a light-red tint, and a **"⚠ Mandatory"** badge.
+
+
+
+## Sensor exposure
+
+`sensor.taskmate_pending_approvals` carries the open misses:
+
+| Attribute | Type | Description |
+| --- | --- | --- |
+| `mandatory_misses` | list | Open mandatory-miss review items |
+| `pending_mandatory_misses` | int | Count of open misses |
+
+Each entry in `mandatory_misses` has these fields:
+
+| Field | Description |
+| --- | --- |
+| `id` | Miss ID — pass this as `miss_id` to the services above |
+| `chore_id` | ID of the missed chore |
+| `child_id` | ID of the child who missed it |
+| `chore_name` | Display name of the chore |
+| `child_name` | Display name of the child |
+| `due_date` | ISO date the chore was missed |
+| `period_id` | The time period that closed (`anytime` for all-day chores) |
+| `penalty_points` | Points snapshotted at creation (so later chore edits don't change an open miss) |
+| `postpone_count` | How many times the miss has been postponed |
+| `created_at` | When the miss was raised |
+
+## Related
+
+- [Penalties](Penalties.md) — fixed, named point deductions
+- [Reminder Escalation](Reminder-Escalation.md) — nudge → reminder → parent-alert ladder for overdue misses
+- [Approvals Card](Approvals-Card.md) — where misses are reviewed
+- [Chores](Chores.md) — the chore editor and chore fields
+- [Chore Scheduling](Chore-Scheduling.md) — time-of-day periods and recurrence
+- [Services](Services.md) — `apply_mandatory_penalty`, `postpone_mandatory_chore`, `dismiss_mandatory_chore`
diff --git a/wiki/Mood-Check-In.md b/wiki/Mood-Check-In.md
new file mode 100644
index 00000000..a98adaaa
--- /dev/null
+++ b/wiki/Mood-Check-In.md
@@ -0,0 +1,83 @@
+# Mood Check In
+
+At the end of the day, once their chores are done, the child card asks **How was your day?** The child taps one of five faces. It takes a second, and over a few weeks it shows you how the days have felt: a run of tough days is worth a chat. If you like, TaskMate can also send you a gentle push when a child says their day was sad or cross.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## On the Child Card
+
+The check-in appears at the bottom of the [child card](Dashboard-Cards.md#child-card) once every chore the child owes today is done. Chores not due today, ones still locked, and open-ended "I did something extra" chores don't hold it back.
+
+| Face | Mood | Stored as |
+|------|------|-----------|
+| 😄 | Great | `great` |
+| 🙂 | Good | `good` |
+| 😐 | OK | `ok` |
+| 😢 | Sad | `sad` |
+| 😠 | Cross | `upset` |
+
+After tapping, the strip reads **Today felt 🙂**. There's one mood per child per day: logging again replaces it.
+
+To hide the check-in on a card:
+
+```yaml
+type: custom:taskmate-child-card
+entity: sensor.taskmate_overview
+child_id: 8e16ad66b23f404e
+show_mood: false
+```
+
+In the editor it's **Show the end-of-day mood check-in**.
+
+---
+
+## Seeing the Trend
+
+**TaskMate panel → Insights → Moods**
+
+
+
+**How the days felt** shows a row of faces per child for the last 7, 14 or 30 days, with tough days (sad or cross) shaded and a count of how many days were logged. Days with no answer show just the weekday letter.
+
+Today's mood also shows as a **Mood** pill on each child's card on the panel's **Today** page.
+
+Moods are kept for 90 days.
+
+---
+
+## The Tough-Day Notification
+
+**Tough day** is **off by default**. Switch it on under **Notifications** and parents get a push when a child picks the sad or cross face:
+
+> 😢 Vaiha had a tough day today. Maybe check in?
+
+Great, good and OK days never send anything.
+
+---
+
+## Events
+
+Every check-in fires `taskmate_mood_logged` with `child_id`, `child_name`, `mood` and `emoji`, and shows as **Mood logged** on the child's [event entity](Event-Entities.md). A sad or cross day also fires `taskmate_mood_low`, whether or not the Tough day notification is on.
+
+---
+
+## Service
+
+| Service | Fields | Description |
+|---------|--------|-------------|
+| `taskmate.log_mood` | `child_id`, `mood` (`great`, `good`, `ok`, `sad` or `upset`) | Log today's mood. One per day; logging again replaces it |
+
+Each child's entry in `sensor.taskmate_overview`'s `children` attribute carries `mood_today` once they've answered.
+
+---
+
+## Related
+
+- [Help Requests](Help-Requests.md) — the "I'm stuck" button
+- [Sick Days](Sick-Days.md) — a day off when a child is unwell
+- [Insights](Insights.md) — the other reports
+- [Notifications](Notifications.md)
diff --git a/wiki/Multi-Parent-Approval-Routing.md b/wiki/Multi-Parent-Approval-Routing.md
new file mode 100644
index 00000000..c3548a94
--- /dev/null
+++ b/wiki/Multi-Parent-Approval-Routing.md
@@ -0,0 +1,50 @@
+# Multi Parent Approval Routing
+
+By default every approval buzzes every parent. Two other modes are available via the `parent_routing` setting, for households where that gets noisy.
+
+
+
+| Mode | Behaviour |
+|------|-----------|
+| `all` *(default)* | Every enabled parent, as before |
+| `home` | Only parents whose presence entity says they're here |
+| `round_robin` | One parent per notification, rotating |
+
+---
+
+## Presence Entities
+
+For `home` mode, give each parent a **presence entity** in the notification settings — a `device_tracker.*`, a `person.*`, or anything that reads `home` / `on` / `true` / `present`.
+
+---
+
+## Every Fallback Errs Towards Over-Notifying
+
+An unseen approval is worse than a redundant buzz, so every failure path widens the audience rather than narrowing it:
+
+- **Nobody home** → everyone is told, not nobody.
+- **No presence entity set** → that parent counts as available and is never silently cut out.
+- **Broken or unavailable presence sensor** → fails open.
+- **Round-robin state pointing at a deleted parent** → starts from the beginning rather than wedging.
+
+---
+
+## Round-Robin Detail
+
+Round-robin position is tracked **per notification type**, so a reward claim doesn't advance the chore-approval rotation. Each kind of approval keeps its own place in the queue.
+
+---
+
+## Children Are Never Affected
+
+None of this touches child notifications. A reminder for a child must always reach that child — routing applies only to the parent-facing approvals.
+
+---
+
+## Related
+
+- [Notifications](Notifications.md) — the full notification system, actionable callbacks and bus events
+- [Quiet Hours](Quiet-Hours.md) — per-child do-not-disturb windows
+- [Reminder Escalation](Reminder-Escalation.md) — nudge → reminder → parent alert
+- [Parent Access](Parent-Access.md) — giving a second parent control without HA admin rights
+- [Settings](Settings.md) — where `parent_routing` lives
diff --git a/wiki/NFC-Tag-Completion.md b/wiki/NFC-Tag-Completion.md
new file mode 100644
index 00000000..27c2062a
--- /dev/null
+++ b/wiki/NFC-Tag-Completion.md
@@ -0,0 +1,114 @@
+# NFC Tag Completion
+
+Stick an NFC tag (or print a QR code) where a chore actually happens: on the dishwasher, by the cat's bowl, on the back door where the bins go out. When a child scans it with the Home Assistant companion app, the chore is ticked off for them. No dashboard, no hunting for the right button.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## How It Works
+
+```
+Child scans the tag with the HA companion app → TaskMate finds the chore(s) linked to that tag → the chore is completed for that child
+```
+
+Home Assistant already has **tags**: NFC stickers and QR codes that the companion app can scan. TaskMate listens for those scans. Every chore linked to the scanned tag is considered, and the completion goes through exactly the same path as tapping **Done** on the child card.
+
+That means all the usual rules still apply:
+
+- A chore that **needs approval** goes into the approval queue as normal.
+- **Schedules, availability, daily limits, weekly targets, dependencies and rotation** are all respected. A tag can't complete a chore that isn't due for that child today.
+- Once today's occurrence is used up, scanning again does nothing.
+
+---
+
+## Setting It Up
+
+### 1. Create the tag in Home Assistant
+
+Write an NFC sticker with the companion app, or create a tag under **Settings → Tags** in Home Assistant and print its QR code. Give it a friendly name, like *Dishwasher*.
+
+### 2. Link it to the chore
+
+**TaskMate panel → Chores → edit a chore → More options → NFC / QR tags**
+
+| Field | Description |
+|-------|-------------|
+| **Tag chips** | Every tag Home Assistant knows about is listed as a chip. Tap one to link it to this chore, tap again to unlink it. |
+| **Tag ID** | Type a tag ID and press **Add tag** if the tag isn't in Home Assistant's list yet. Typed IDs show as chips too, so you can remove them later. |
+
+A chore can have up to **10** tags. The section header shows how many are linked.
+
+---
+
+## Who Gets the Credit?
+
+TaskMate works out which child scanned from the Home Assistant user who did the scanning:
+
+| Situation | Result |
+|-----------|--------|
+| The scanning user is **linked to a child** (Children → Edit → *Link to Home Assistant user*) | That child gets the completion. |
+| The scanning user **isn't linked** to any child, and the chore is assigned to **exactly one** child | That child gets the completion. |
+| The scanning user isn't linked, and the chore is shared by several children | Nothing happens. TaskMate can't tell who it was, so it doesn't guess. |
+
+If you use **Require a linked account per child**, that rule still holds: a tag can't be used to get around it.
+
+### One tag, several children
+
+One tag can serve several chores. A common pattern is a separate "Empty the dishwasher" chore per child, all linked to the same dishwasher tag. Whoever scans gets their own chore ticked off.
+
+---
+
+## Chores a Tag Can't Complete
+
+A tap carries no photo, note or timer, so these chore types are skipped when their tag is scanned:
+
+- **[Photo proof](Photo-Proof.md)** chores
+- **[Open-ended](Open-Ended-Chores.md)** chores (the child has to describe what they did)
+- **[Timed](Timed-Tasks.md)** chores
+
+The chore editor shows a warning in the NFC / QR tags section if you link a tag to one of these.
+
+---
+
+## Double Scans
+
+Phones often read a single NFC tap twice. A repeat scan by the same child within **60 seconds** of a completion is ignored, even if the chore's daily limit would allow another one.
+
+---
+
+## For Automations
+
+Each successful tag completion fires the `taskmate_tag_completion` event (as well as the usual `taskmate_chore_completed`):
+
+| Field | Description |
+|-------|-------------|
+| `tag_id` | The tag that was scanned |
+| `device_id` | The phone that scanned it |
+| `child_id` / `child_name` | Who got the credit |
+| `chore_id` / `chore_name` | The chore that was completed |
+| `completion_id` | The new completion |
+| `pending_approval` | `true` if it's waiting for a parent |
+
+Every tag completion is also written to the [Admin Audit Log](Admin-Audit-Log.md).
+
+---
+
+## Good Candidates
+
+- **Emptying the dishwasher**: tag on the dishwasher door
+- **Feeding pets**: tag by the food bowl
+- **Putting the bins out**: tag on the back door or the bin store
+- **Watering plants**: tag on the watering can
+
+Anything with a clear "I'm standing where the job is" moment.
+
+---
+
+## Related
+
+- [Chores](Chores.md) — creating and configuring chores
+- [Children](Children.md) — linking a child to a Home Assistant user
+- [Automations](Automations.md) — reacting to TaskMate events
diff --git a/wiki/Notifications.md b/wiki/Notifications.md
new file mode 100644
index 00000000..c93e9120
--- /dev/null
+++ b/wiki/Notifications.md
@@ -0,0 +1,590 @@
+# Notifications
+
+TaskMate has a full notification system with built-in notification types, per-recipient routing, custom scheduled notifications, actionable mobile callbacks, and bus events for power users.
+
+
+
+---
+
+## Overview
+
+```
+Event occurs (chore completed, streak at risk, bedtime, badge earned)
+ │
+ ├─ Check notification type is enabled (master toggle)
+ ├─ Check recipient routing matrix
+ ├─ Check time gate (if applicable)
+ │
+ ├─ Send persistent HA notification
+ ├─ Send push notification (per recipient's notify service)
+ ├─ Fire bus event (taskmate_* event)
+ │
+ └─ Actionable notifications include Approve/Reject buttons (mobile)
+```
+
+---
+
+## Built-in Notification Types
+
+TaskMate ships with these built-in notification types:
+
+| Type | ID | Audience | Time-Gated | Actionable | Default |
+|------|-----|----------|-----------|------------|---------|
+| **Bedtime Reminder** | `bedtime_reminder` | Children | Yes (per-recipient time) | No | Off |
+| **Streak at Risk** | `streak_at_risk` | Children | Yes (global cutoff) | No | Off |
+| **All Chores Done** | `all_chores_done` | Both | No | No | Off |
+| **Badge Earned** | `badge_earned` | Both | No | No | On |
+| **Pending Chore Approval** | `pending_chore_approval` | Parents | No | Yes | On |
+| **Pending Reward Claim** | `pending_reward_claim` | Parents | No | Yes | On |
+| **Streak Milestone** | `streak_milestone` | Both | No | No | Off |
+| **Level Up** | `level_up` | Both | No | No | Off |
+| **Celebration** | `celebration` | Both | No | No | Off |
+| **Weekly Digest** | `weekly_digest` | Parents | No | No | Off |
+| **Mandatory Reminder** | `mandatory_reminder` | Children | No | No | Off |
+| **Mandatory Parent Alert** | `mandatory_parent_alert` | Parents | No | No | Off |
+| **Monthly Report** | `monthly_report` | Parents | No | No | Off |
+| **Season Champion** | `season_champion` | Both | No | No | Off |
+| **Family Goal Reached** | `family_goal_reached` | Both | No | No | Off |
+| **Birthday** | `birthday` | Children | Yes (per-recipient time, 08:00 if unset) | No | Off |
+| **Streak Freeze Used** | `streak_freeze_used` | Both | No | No | Off |
+| **Arrived Home** | `presence_arrival` | Children | No | No | Off |
+| **Item Rejected** | `item_rejected` | Children | No | No | Off |
+| **Recap Ready** | `recap_ready` | Both | Yes (recap send time) | No | Off |
+| **Bounty Posted** | `bounty_posted` | Children | No | No | Off |
+| **Bounty Claim Lapsing** | `bounty_claim_lapsing` | Children | No | No | Off |
+| **Wish Requested** | `wish_requested` | Parents | No | No | Off |
+| **Wish Pledged** | `wish_pledged` | Children | No | No | Off |
+| **Inspection Started** | `inspection_started` | Children | No | No | Off |
+| **Inspection Passed** | `inspection_passed` | Children | No | No | Off |
+| **Inspection Reminder** | `inspection_reminder` | Parents | No | No | **On** |
+| **Auction Opened** | `auction_opened` | Children | No | No | Off |
+| **Auction Closing** | `auction_closing` | Children | No | No | Off |
+| **Auction Result** | `auction_result` | Both | No | No | Off |
+| **Asked for help** | `help_requested` | Parents | No | No | **On** |
+| **Tough day** | `mood_low` | Parents | No | No | Off |
+| **Weekly goal reached** | `weekly_goal_reached` | Both | No | No | Off |
+| **Penalty earned back** | `penalty_redeemed` | Both | No | No | Off |
+| **Raffle drawn** | `raffle_drawn` | Both | No | No | Off |
+| **Pet grew up** | `pet_evolved` | Both | No | No | Off |
+
+The 15 rows from **Birthday** to **Auction Result** were added in v6.0.0. All of them start **switched off**, apart from the parent **Inspection Reminder**, which only ever fires for an inspection a parent started. Turn on the ones you want on the Notifications tab.
+
+The last 6 rows were added in v7.0.0. **Asked for help** starts **switched on**, because an "I'm stuck" button that reaches nobody is worse than no button; the rest start off.
+
+> **Upgrading to v7.0.0.** A notification type your install has never seen before now starts in its default state, exactly as on a fresh install, and is routed to every parent. So **Asked for help** is switched on for you when you upgrade; the other new types arrive switched off. Types you had already configured are left alone.
+
+### Bedtime Reminder
+
+Sends a reminder to children who still have incomplete chores. Each recipient can have their own bedtime — e.g. 19:30 for younger children, 20:30 for older ones.
+
+### Streak at Risk
+
+Alerts children who haven't completed a chore today and are at risk of losing their streak. Uses a global cutoff time (configurable in the recipient matrix).
+
+### All Chores Done
+
+Fires immediately when a child finishes every chore assigned to them for the day.
+
+### Badge Earned
+
+Fires when a child earns a new achievement badge (auto or manual). See [Achievement Badges](Achievement-Badges.md).
+
+### Pending Chore Approval
+
+Sent to parent recipients when a child completes a chore that requires approval. Includes **Approve** and **Reject** action buttons on mobile.
+
+### Pending Reward Claim
+
+Sent to parent recipients when a child claims a reward. Includes **Approve** and **Reject** action buttons on mobile.
+
+### Streak Milestone
+
+Fires when a child reaches a streak milestone (e.g. a 3-, 7-, 14-day streak) and is awarded the milestone bonus. The bonus itself has always been granted; this type announces it. **Off by default** — enable it on the Notifications tab. One notification fires per newly reached milestone. Milestone days/bonuses come from the **Streak Milestones** setting (see [Bonus Points](Bonus-Points.md)).
+
+### Level Up
+
+Fires when a child gains an XP level. **Off by default.** See [Levels and XP](Levels-and-XP.md).
+
+### Celebration
+
+A single, tier-scaled notification for notable moments (level-ups, completed quests/challenges, and similar). It is opt-in and only sent when the moment meets a minimum tier:
+
+- Enable the `celebration_notify` setting to turn it on.
+- `celebration_notify_min_tier` (default `2`) sets the smallest tier that notifies (1 = small, 2 = medium, 3 = epic).
+
+The matching `taskmate_celebration` bus event always fires regardless of this notification (see [Celebrations](Celebrations.md)).
+
+### Weekly Digest
+
+A Sunday-evening recap sent to parents summarising each child's week. **Off by default.** See [Weekly Digest](Weekly-Digest.md) for the schedule, contents and configuration.
+
+### Mandatory Reminder
+
+Nudges a child whose [mandatory chore](Mandatory-Chores.md) is overdue, then reminds them again after the escalation delay. Sent only to the affected child, and held back during that child's [quiet hours](Quiet-Hours.md). **Off by default.** This is the child-facing half of the [Reminder Escalation](Reminder-Escalation.md) ladder.
+
+### Mandatory Parent Alert
+
+Alerts a parent when a child's [mandatory chore](Mandatory-Chores.md) is still incomplete after the parent escalation delay. **Off by default.** This is the top rung of the [Reminder Escalation](Reminder-Escalation.md) ladder.
+
+### Monthly Report
+
+A per-child recap of the previous calendar month — chores completed, points earned, level and best streak — sent to parents on the **1st of each month**. It is the longer-period sibling of the weekly digest. **Off by default.** See [Weekly Digest](Weekly-Digest.md).
+
+### Season Champion
+
+Announces the winner of the previous month's leaderboard at the start of a new month. **Off by default.**
+
+### Family Goal Reached
+
+Fires when the family hits a shared points goal. **Off by default.**
+
+### Birthday *(v6.0.0)*
+
+A morning "happy birthday" to the child on their [birthday](Birthday-Mode.md), telling them how much every chore pays today. Sent at each recipient's own time, or 08:00 when none is set.
+
+### Streak Freeze Used *(v6.0.0)*
+
+Sent when a [streak freeze](Streak-Freezes.md) token saves a child's streak on a missed day, with how many tokens are left.
+
+### Arrived Home *(v6.0.0)*
+
+Part of [Presence-Aware Reminders](Presence-Aware-Reminders.md). While a child is away, their bedtime, streak-at-risk, mandatory and custom reminders are held back. When they get home, this sends one "🏠 You're home — 3 chores left today" message instead of a backlog. Only sent if the child was away for at least **Only after being away for** minutes (default 30, set on this type's row), and never during quiet hours.
+
+### Item Rejected *(v6.0.0)*
+
+Tells the child a chore or reward claim was sent back, including the parent's [reason](Reject-Reasons.md) when one was given.
+
+### Recap Ready *(v6.0.0)*
+
+Announces a new [recap](Recaps.md): one message per child, plus one grouped message for parents. Recaps are built at midnight, and this waits for the **Send at** time in **Settings → Recaps** (default 08:00). It is switched on for you the first time you turn recaps on; the per-audience switches live in **Settings → Recaps**.
+
+### Bounty Posted / Bounty Claim Lapsing *(v6.0.0)*
+
+For the [Bounty Board](Bounty-Board.md). **Bounty Posted** goes to the children a new bounty is open to, when the parent leaves **Notify children** ticked. **Bounty Claim Lapsing** warns the child holding a claim 15 minutes before it runs out and the bounty goes back on the board.
+
+### Wish Requested / Wish Pledged *(v6.0.0)*
+
+For the [Wishlist](Wishlist.md). **Wish Requested** tells parents a child has added a wish waiting for approval. **Wish Pledged** tells the child someone has pledged points towards one of their wishes.
+
+### Inspection Started / Inspection Passed / Inspection Reminder *(v6.0.0)*
+
+For [Surprise Inspections](Surprise-Inspections.md). **Inspection Started** tells the child one is coming (not sent for a secret check). **Inspection Passed** tells them it passed and what bonus they got. **Inspection Reminder** reminds the parent 30 minutes before an undecided inspection closes; this one is **on** by default.
+
+### Auction Opened / Auction Closing / Auction Result *(v6.0.0)*
+
+For [Chore Auctions](Chore-Auctions.md). **Auction Opened** and **Auction Closing** (bidding closes within the hour) go to the children who may bid, when the parent ticks "tell children". **Auction Result** goes to them and to parents. No notification ever reveals another child's bid.
+
+### Asked for help / Tough day *(v7.0.0)*
+
+**Asked for help** tells parents a child tapped "I'm stuck" on a chore, with their message if they wrote one. Answer it from the admin panel's **Today** page (or with `taskmate.answer_help`) so the child's card stops saying help is on its way. See [Help Requests](Help-Requests.md). **Tough day** tells parents a child picked the sad or cross face in the end-of-day [mood check-in](Mood-Check-In.md).
+
+### Weekly goal reached / Penalty earned back *(v7.0.0)*
+
+**Weekly goal reached** goes to the child and parents when a child reaches the [weekly goal](Weekly-Goals.md) they set themselves. **Penalty earned back** goes out when a child does a penalty's [make-it-right](Make-It-Right-Penalties.md) chore and gets points back.
+
+### Raffle drawn / Pet grew up *(v7.0.0)*
+
+**Raffle drawn** announces a [raffle](Raffles.md)'s winner and how many tickets were in the draw. **Pet grew up** tells the child and parents a [virtual pet](Virtual-Pets.md) reached a new stage, turned legendary, laid an egg or reached a new pet level.
+
+---
+
+## Notification Messages
+
+Each built-in type has a fixed message template. The English wording is shown below.
+
+**Your language (v6.2.0).** Push notifications follow Home Assistant's language, set under **Settings → System → General**, the same as the cards and the admin panel. That covers every built-in message, the **Approve** / **Reject** buttons and the reject reason box, the "Open the TaskMate panel…" hint for non-mobile backends, celebration and recap messages, auction results, the weekly digest and monthly report lines, and month and weekday names in dates. A German household gets, for example:
+
+> Alex hat „Spülmaschine ausräumen“ erledigt (+5 Punkte) – wartet auf Freigabe.
+> Buttons: **Genehmigen / Ablehnen**
+
+Changing Home Assistant's language takes effect straight away, with no restart. Where a language has no translation for a message, it goes out in English. Your own [custom notifications](#custom-notifications) are sent exactly as you wrote them. See [Localization](Localization.md#push-notifications) for the list of languages.
+
+| Type | Message |
+|------|---------|
+| Bedtime Reminder | `"{child_name}, you still have chores to do before bedtime."` |
+| Streak at Risk | `"{child_name}, complete a chore today to keep your {streak}-day streak!"` |
+| All Chores Done | `"{child_name} finished every chore today!"` |
+| Badge Earned | `"{child_name} earned the {badge_name} badge!"` |
+| Pending Chore Approval | `"{child_name} completed '{chore_name}' (+{points} {points_name}) — awaiting approval."` |
+| Pending Reward Claim | `"{child_name} claimed '{reward_name}' ({cost} {points_name}) — awaiting approval."` |
+| Streak Milestone | `"{child_name} hit a {days}-day streak — +{points} {points_name}!"` |
+| Level Up | `"{child_name} reached level {level}! 🎉"` |
+| Celebration | `"🎉 {message}"` |
+| Weekly Digest | `"TaskMate weekly digest:\n{summary}"` |
+| Mandatory Reminder | `"{child_name}, you still need to do '{chore_name}'."` |
+| Mandatory Parent Alert | `"{child_name} still hasn't done the mandatory chore '{chore_name}'."` |
+| Monthly Report | `"TaskMate {month} report:\n{summary}"` |
+| Season Champion | `"🏆 {child_name} won the {month} leaderboard with {points} {points_name}!"` |
+| Family Goal Reached | `"🎉 Family goal reached: {goal_name}! Time for {goal_reward}."` |
+| Birthday | `"🎂 Happy birthday, {child_name}! Every chore pays {multiplier}× today."` |
+| Streak Freeze Used | `"❄️ A streak freeze saved {child_name}'s {streak}-day streak ({freezes_left} left)."` |
+| Arrived Home | `"🏠 You're home, {child_name} — {count} chores left today."` |
+| Item Rejected | `"↩️ {child_name}, '{item_name}' was sent back{reason_text}"` |
+| Recap Ready | `"✨ Your {period} recap is ready, {child_name}! Tap to watch it."` |
+| Bounty Posted | `"🏁 New bounty: {bounty_name} — {points} {points_name}. First to claim it gets it!"` |
+| Bounty Claim Lapsing | `"⏳ {child_name}, {minutes} minutes left to finish '{bounty_name}' before it goes back on the board."` |
+| Wish Requested | `"{child_name} wished for '{wish_name}' ({target} {points_name}) — waiting for your approval."` |
+| Wish Pledged | `"💝 {pledger} added {points} {points_name} to your wish '{wish_name}'!"` |
+| Inspection Started | `"🔍 {child_name}, a grown-up is coming to inspect '{chore_name}' before {until}. Keep it looking great for +{bonus} {points_name}!"` |
+| Inspection Passed | `"🌟 Inspection passed, {child_name}! '{chore_name}' looked great: +{bonus} {points_name}{note_text}"` |
+| Inspection Reminder | `"🔍 {child_name}'s '{chore_name}' inspection closes in {minutes} minutes — pass or fail it before {until}."` |
+| Auction Opened | `"🔨 New auction: {chore_name} on {date}, up to {max_points} {points_name}. Lowest bid wins!"` |
+| Auction Closing | `"⏳ {child_name}, bidding on '{chore_name}' closes in {minutes} minutes."` |
+| Auction Result | `"🔨 Auction closed: {result_text}"` |
+| Asked for help | `"🙋 {child_name} needs help with '{chore_name}'{message_text}"` |
+| Tough day | `"{emoji} {child_name} had a tough day today. Maybe check in?"` |
+| Weekly goal reached | `"🎯 {child_name} reached their weekly goal of {target} {points_name} — +{bonus} bonus!"` |
+| Penalty earned back | `"🤝 {child_name} made it right with '{chore_name}' and earned back {points} {points_name}."` |
+| Raffle drawn | `"🎟️ {raffle_name}: {winner_name} won! ({tickets} tickets in the draw)"` |
+| Pet grew up | `"{news}"` — one of: `"🐣 {pet_name} just grew up! Have a look at {child_name}'s pet."`, `"✨ {pet_name} turned legendary! {child_name}'s pet is shining gold."`, `"🥚 {pet_name} laid an egg! {child_name} can hatch a new pet."`, `"💖 {pet_name} reached pet level {pet_level}!"` |
+
+---
+
+## Testing a Notification
+
+To confirm that a notification type is routed correctly without waiting for the real trigger, use the **test notification** feature. It sends a sample message to that type's enabled recipients **ignoring the master on/off toggle**, so you can verify routing before you switch the type on. The sample message is prefixed with `[TEST] ` and filled with placeholder data (child "Alex", chore "Tidy room", and so on). Since v6.2.0 the sample names are in your language too. A test send does **not** fire a bus event.
+
+Each notification type row in the **Admin Panel → Notifications** tab has a **Send test** button. You can also call the service directly:
+
+```yaml
+action: taskmate.test_notification
+data:
+ type_id: streak_milestone
+```
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `type_id` | Yes | Notification type id, e.g. `pending_chore_approval`, `badge_earned`, `streak_milestone` |
+
+A persistent notification is also created for the test, the same as a real send.
+
+---
+
+## Actionable Notifications (Mobile)
+
+The `pending_chore_approval` and `pending_reward_claim` types send actionable notifications via the HA Companion app. The notification includes two tap actions:
+
+- **Approve** — approve the pending item directly from the notification
+- **Reject** — reject the pending item
+
+Action identifiers follow the format `TASKMATE_APPROVE_{entry_id}` and `TASKMATE_REJECT_{entry_id}`. Since v6.2.0 the button labels follow Home Assistant's language; the identifiers don't change, so automations that listen for them keep working.
+
+**Reject with a reason (v6.0.0).** Tapping **Reject** opens a text box on the phone ("Reason (optional)"). Whatever you type is saved as the [reject reason](Reject-Reasons.md) and shown to the child; sending it empty is a plain reject.
+
+**Star ratings (v6.0.0).** With [quality ratings](Quality-Ratings.md) switched on, a chore approval push shows **★**, **★★** and **★★★** buttons instead of **Approve**, so you can rate from the lock screen (action IDs `TASKMATE_RATE_{n}_{entry_id}`). Android shows at most three buttons, so there the stars take priority and Reject is done from the panel or the approvals card. Reward claims always keep Approve / Reject.
+
+> **Requirement:** The HA Companion app must be installed on the parent's device and the notify service must be a `mobile_app` service.
+
+### Auto-clearing when reviewed *(v4.4.4+)*
+
+Once a pending chore or reward is reviewed — approved **or** rejected, individually or via **Approve All** — TaskMate automatically dismisses its push from the Companion app, so a big approval sweep no longer leaves a pile of stale notifications on the phone. This is done by re-sending the notification's `tag` with the Companion app's `clear_notification` message.
+
+Clearing is limited to `mobile_app.*` notify targets. Other backends (Telegram, email, persistent) are never sent a clear request — they would render it as literal text — so there is no extra notification noise and no per-recipient toggle is needed.
+
+### Graceful Fallback for Non-mobile_app Backends
+
+Tap actions only render in the HA Companion app. Other notify backends — Telegram, email, SMS, and so on — silently ignore them. Rather than send dead buttons to those recipients, TaskMate detects a non-`mobile_app` notify service and instead appends a hint to the message:
+
+> *Open the TaskMate panel to approve or reject.*
+
+In addition, a **persistent notification** is always created in Home Assistant for every notification type (see [Persistent Notifications](#persistent-notifications) below), so even a recipient with no usable push backend has a way to act from the HA sidebar.
+
+The notify service must be in the `notify.*` domain; other domains are rejected and logged.
+
+---
+
+## Tap-to-Open Navigation *(v5.0.2+)*
+
+Tapping the **body** of a TaskMate notification can open a place of your choosing — the TaskMate panel, a dashboard, or any URL. This is separate from the Approve/Reject action buttons above: an approval push keeps its buttons *and* gains a tap target.
+
+Configure it in the admin panel under **Notifications**, in the built-in notifications card:
+
+- **When tapped, open** (global) — the default target for every notification. Ships defaulting to the TaskMate panel, `/taskmate-admin`.
+- **Per-notification override** — each row in the matrix has its own *tap opens* field. Leave it blank to inherit the global default, or set a specific target (for example, point **Pending Chore Approval** and **Pending Reward Claim** at a parents' approval dashboard).
+
+**Accepted values** (same on both platforms):
+
+| Value | Effect |
+| --- | --- |
+| `/taskmate-admin` | Opens the TaskMate admin panel |
+| `/lovelace/parents` | Opens a Lovelace dashboard path |
+| `https://…` | Opens a full URL |
+| `noAction` | Tap does nothing (disables navigation for that scope) |
+| *(empty)* | Global: no navigation. Per-type: inherit the global default. |
+
+Anything else is rejected when saving — the target opens on the *recipient's* phone, so only dashboard paths, `http(s)` URLs and `noAction` are allowed (no `intent://`, `app://` or other app schemes).
+
+Under the hood the value is emitted as both the Companion app's `clickAction` (Android) and `url` (iOS), for `mobile_app.*` notify targets only. Other backends (Telegram, email, persistent) never receive it.
+
+> **Upgrade note:** from v5.0.2 the global default is the TaskMate panel (`/taskmate-admin`), so notification taps open the TaskMate panel out of the box. To restore the previous "open wherever the app was last" behaviour, clear the **When tapped, open** field or set it to `noAction`.
+
+---
+
+## Notification Grouping *(v5.3.0+)*
+
+TaskMate stamps every push with a **group key** so the Companion app stacks its
+alerts into one bundle, instead of scattering them through everything else Home
+Assistant sends you.
+
+This is **on by default** with the key `taskmate` — there is nothing to set up.
+
+Configure it in the admin panel under **Notifications**, the same place as the
+tap target:
+
+- **Group key** (global) — the default key for every notification.
+- **Per-notification override** — each row in the matrix has its own *group*
+ field. Leave it blank to inherit the global key, or set a specific one to
+ split TaskMate into separate stacks (for example approvals in one bundle and
+ badges in another).
+
+| Value | Effect |
+| --- | --- |
+| `taskmate` | The shipped default — all TaskMate alerts in one stack |
+| `family-chores` | Any custom key you like |
+| *(empty)* | Global: grouping off. Per-type: inherit the global key. |
+
+**Key rules:** 64 characters or fewer, no spaces and no control characters. Use
+`family-chores`, not `family chores` — an invalid key is rejected when saving
+and the field reverts to the last good value.
+
+### What each platform reads
+
+| Platform | Key sent | Effect |
+| --- | --- | --- |
+| Android | `data.group` | Notifications collapse into one group |
+| iOS | `push.thread-id` | Notifications thread together |
+
+Both are sent with the same value and each platform ignores the other's, so a
+single setting covers both. Like the tap target, the keys are only added for
+`mobile_app.*` notify targets — Telegram, email and persistent notifications
+never receive them. [Custom notifications](#custom-notifications) always use the
+global key, since they have no notification type of their own.
+
+---
+
+## Recipients
+
+TaskMate supports two types of notification recipients:
+
+### Child Recipients
+
+Each child in TaskMate is automatically a recipient. Their notify service can be configured in the admin panel's Notifications tab (e.g. `notify.mobile_app_noahs_tablet`). Children only receive notifications from types with audience `child` or `both`.
+
+### Parent Recipients
+
+Parents are added manually in the Notifications tab. Each parent recipient has:
+
+| Field | Description |
+|-------|-------------|
+| **Name** | Display name (e.g. "Dad") |
+| **Notify Service** | HA notify service (e.g. `notify.mobile_app_dads_phone`) |
+| **Enabled** | Master on/off toggle |
+
+Parents only receive notifications from types with audience `parent` or `both`.
+
+---
+
+## Recipient Routing Matrix
+
+The routing matrix controls which recipients get which notification types. It is configured in the **Admin Panel → Notifications → Recipient Matrix**.
+
+The matrix is a table with:
+- **Rows** = notification types (15 built-in)
+- **Columns** = recipients (all children + all parent recipients)
+- **Cells** = enable/disable checkbox per type per recipient
+
+Additional per-type settings in the matrix:
+- **Bedtime Reminder**: per-recipient time input (each child can have a different bedtime)
+- **Streak at Risk**: global cutoff time input (one time for all recipients)
+
+Cells that don't apply (e.g. a child column for a parent-audience type) show a dash and are not interactive.
+
+### Master Toggle
+
+Each notification type has a **master enable/disable** toggle. When disabled, the notification does not fire for any recipient regardless of individual routing.
+
+---
+
+## Custom Notifications
+
+Parents can create their own scheduled notifications for anything not covered by the built-in types.
+
+### Custom Notification Fields
+
+| Field | Description |
+|-------|-------------|
+| **Name** | Display name (e.g. "Homework Reminder") |
+| **Message Template** | Text with `{child_name}` and `{time}` placeholders. Sent as written, never translated |
+| **Time** | Scheduled dispatch time in `HH:MM` format |
+| **Day Mask** | Which days of the week this notification fires (Mon–Sun toggles) |
+| **Recipients** | Which children and/or parents receive it |
+| **Enabled** | On/off toggle |
+
+### Creating a Custom Notification
+
+1. Open the **Admin Panel → Notifications tab**
+2. Scroll to the **Custom Notifications** section
+3. Click **Add Custom Notification**
+4. Fill in the name, message template, time, days, and recipients
+5. Save
+
+### Example Use Cases
+
+- **"Pack your bag!"** — 19:00 on school nights (Mon–Thu) to children
+- **"Lunch boxes?"** — 07:00 on weekdays to a parent
+- **"Weekend chore time!"** — 10:00 on Sat/Sun to all children
+
+---
+
+## Bus Events
+
+Every notification fires a Home Assistant bus event, even if the master toggle is off (in which case the `recipients` list will be empty). Power users can use these in their own automations.
+
+### Notification-Type Event Names
+
+Each notification type fires a matching `taskmate_` event, except the 11 types marked † below. Their feature already fires a `taskmate_` event of its own, so since **v6.1.0** the notification system fires `taskmate__notification` for them instead:
+
+| Event | Fired When |
+|-------|------------|
+| `taskmate_bedtime_reminder` | Bedtime reminder dispatched |
+| `taskmate_streak_at_risk` | Streak at risk alert dispatched |
+| `taskmate_all_chores_done` | Child finished all chores |
+| `taskmate_badge_earned_notification` † | Badge awarded to a child |
+| `taskmate_pending_chore_approval` | Chore completion awaiting approval |
+| `taskmate_pending_reward_claim` | Reward claim awaiting approval |
+| `taskmate_streak_milestone` | Streak milestone reached |
+| `taskmate_level_up_notification` † | Child gained an XP level |
+| `taskmate_celebration_notification` † | A notable moment (level-up, quest/challenge complete, …) |
+| `taskmate_weekly_digest` | Weekly digest dispatched |
+| `taskmate_mandatory_reminder` | Mandatory-chore nudge sent to a child |
+| `taskmate_mandatory_parent_alert` | Mandatory chore still undone after the parent delay |
+| `taskmate_monthly_report` | Monthly report dispatched |
+| `taskmate_season_champion_notification` † | Previous month's leaderboard champion announced |
+| `taskmate_family_goal_reached_notification` † | Combined family points reached the goal |
+| `taskmate_birthday`, `taskmate_presence_arrival`, `taskmate_item_rejected`, `taskmate_recap_ready`, `taskmate_bounty_claim_lapsing`, `taskmate_wish_requested`, `taskmate_inspection_reminder`, `taskmate_auction_closing`, `taskmate_auction_result` | (v6.0.0) The matching notification was dispatched |
+| `taskmate_streak_freeze_used_notification` †, `taskmate_bounty_posted_notification` †, `taskmate_wish_pledged_notification` †, `taskmate_inspection_started_notification` †, `taskmate_inspection_passed_notification` †, `taskmate_auction_opened_notification` † | (v6.0.0) The matching notification was dispatched |
+| `taskmate_help_requested`, `taskmate_mood_low`, `taskmate_weekly_goal_reached`, `taskmate_penalty_redeemed`, `taskmate_raffle_drawn`, `taskmate_pet_evolved` | (v7.0.0) The matching notification was dispatched. These features have no separate event of their own, so automate on these. The per-child and family [event entities](Event-Entities.md) re-publish them too |
+| `taskmate_custom_notification` | Custom notification dispatched |
+
+> **† Renamed in v6.1.0.** Before v6.1.0 these 11 notification events used the same name as the feature's own event, so an automation on, say, `taskmate_level_up` ran twice whenever the notification was sent. Now the feature event (no `recipients`, see [Automations](Automations.md)) fires once, and the notification event has the `_notification` suffix. If an automation reads `recipients` from one of these, trigger it on the `_notification` event. A `recipients is not defined` condition added to filter out the duplicate can be removed.
+
+### Event Data
+
+Notification-type events include all context keys for the notification type (e.g. `child_name`, `chore_name`, `points`) plus `recipients` — a list of recipient IDs that were actually sent to. A `test_notification` send does **not** fire a bus event.
+
+Custom notification events include:
+- `id` — custom notification ID
+- `name` — custom notification name
+- `recipients` — list of recipient IDs
+
+### Other Automation Events (v4.0.0)
+
+TaskMate also fires events for penalties, bonuses and reward/chore approvals so you can build your own automations even when no notification is configured. These are **not** routed through the notification system and carry no `recipients` field:
+
+| Event | Fired When |
+|-------|------------|
+| `taskmate_penalty_applied` | A penalty was applied to a child |
+| `taskmate_bonus_applied` | A bonus was applied to a child |
+| `taskmate_reward_approved` | A reward claim was approved |
+| `taskmate_reward_rejected` | A reward claim was rejected |
+| `taskmate_chore_rejected` | A chore completion was rejected |
+
+See [Automations](Automations.md) for the full event reference and example automations.
+
+### Automation Example
+
+```yaml
+alias: Log chore approvals to Discord
+triggers:
+ - trigger: event
+ event_type: taskmate_pending_chore_approval
+actions:
+ - action: notify.discord_webhook
+ data:
+ message: >
+ {{ trigger.event.data.child_name }} completed
+ '{{ trigger.event.data.chore_name }}'
+ (+{{ trigger.event.data.points }} {{ trigger.event.data.points_name }})
+```
+
+---
+
+## Persistent Notifications
+
+Regardless of routing configuration, TaskMate always creates a **persistent notification** in Home Assistant for pending chore approvals and pending reward claims. These appear in the notification bell in the HA sidebar and are automatically dismissed once you approve or reject the item.
+
+---
+
+## Binary Sensor
+
+`binary_sensor.taskmate_has_pending_approvals` turns `on` when there are unapproved chore completions or reward claims. Use it in your own automations for fully custom notification logic.
+
+**Attributes:**
+- `pending_chore_completions` — count of pending chore approvals
+- `pending_reward_claims` — count of pending reward claims
+- `total_pending` — combined total
+
+---
+
+## Migration from Pre-v3.9.0
+
+If you previously used the single **Notification Service** setting, it still works as a fallback — it now lives in the panel's **Settings** tab rather than the removed config flow. For the best experience:
+
+1. Open the **Admin Panel → Notifications tab**
+2. Add yourself as a Parent Recipient with your notify service
+3. Configure the routing matrix to your preferences
+
+---
+
+## Multiple Parents / Devices
+
+Unlike the old single-service setting, the v3.9.0 notification system natively supports multiple parents:
+
+1. Add each parent as a **Parent Recipient** in the Notifications tab
+2. Set each parent's `notify_service` to their device (e.g. `notify.mobile_app_dads_phone`, `notify.mobile_app_mums_phone`)
+3. Enable/disable specific notification types per parent in the routing matrix
+
+---
+
+## Evidence Photos in the Approval Push
+
+When a chore [requires a photo](Photo-Proof.md), that photo is attached to the
+approval notification itself, so you can see the work and approve straight from
+the lock screen without opening the app.
+
+**This only applies to `mobile_app.*` notify services.** The image is delivered
+through the Home Assistant companion app's own push payload, so a persistent
+notification, a Telegram bridge or an e-mail notifier receives the usual text
+message with no picture.
+
+---
+
+## Routing Parent Approvals
+
+By default every approval buzzes every parent. Two other modes are available
+through the `parent_routing` setting — send only to parents who are currently
+home, or share approvals round-robin between them.
+
+Every fallback deliberately errs towards over-notifying: if nobody is home,
+everybody is told rather than nobody. See
+[Multi-Parent Approval Routing](Multi-Parent-Approval-Routing.md) for the detail.
+
+Child notifications are never affected by any of this — a reminder for a child
+must always reach that child.
+
+---
+
+## Related
+
+- [Admin Panel](Admin-Panel.md) — where to configure notifications
+- [Achievement Badges](Achievement-Badges.md) — badge_earned notifications
+- [Weekly Digest](Weekly-Digest.md) — the Sunday parent summary (and monthly report)
+- [Multi-Parent Approval Routing](Multi-Parent-Approval-Routing.md) — route approvals to whoever is home, or round-robin
+- [Quiet Hours](Quiet-Hours.md) — per-child do-not-disturb window
+- [Reminder Escalation](Reminder-Escalation.md) — the mandatory-chore nudge → reminder → parent-alert ladder
+- [Presence-Aware Reminders](Presence-Aware-Reminders.md) — hold reminders while a child is out
+- [Reject Reasons](Reject-Reasons.md), [Quality Ratings](Quality-Ratings.md) — the reason box and star buttons on the approval push
+- [Birthday Mode](Birthday-Mode.md), [Streak Freezes](Streak-Freezes.md), [Recaps](Recaps.md), [Bounty Board](Bounty-Board.md), [Wishlist](Wishlist.md), [Surprise Inspections](Surprise-Inspections.md), [Chore Auctions](Chore-Auctions.md) — v6.0.0 notification types
+- [Automations](Automations.md) — full event reference and automation examples
+- [Services](Services.md) — underlying services
+- [Settings](Settings.md) — legacy notification service setting
diff --git a/wiki/Open-Ended-Chores.md b/wiki/Open-Ended-Chores.md
new file mode 100644
index 00000000..e80ccc61
--- /dev/null
+++ b/wiki/Open-Ended-Chores.md
@@ -0,0 +1,115 @@
+# Open Ended Chores
+
+Children do helpful things that were never on the list — tidying up unprompted, carrying the shopping in, raking the drive. An **open-ended chore** is a standing placeholder for exactly that. The child taps it, describes what they did in their own words, suggests what they think it was worth, and it lands in your approvals queue for you to price.
+
+
+
+---
+
+## How It Works
+
+```
+Child taps the chore → describes it + suggests points → always pending → parent reviews and sets the real points → approve
+```
+
+It reuses the ordinary completion path, so streaks, badges, quests and challenges all behave exactly as they do for any other chore. Nothing about it is a special case.
+
+---
+
+## Setting One Up
+
+Create a chore — "Something extra" works well as a name — and turn on **Open-ended (child describes it)** in the chore dialog in the [Admin Panel](Admin-Panel.md). It sits directly beneath *Require photo proof*.
+
+Two settings worth getting right:
+
+| Setting | Suggestion |
+|---------|------------|
+| **Points** | Leave it at **0**. The real number is the one you type when you approve. |
+| **Daily limit** | Raise it (5–10). One open-ended chore covers every spontaneous job, so a limit of 1 means the second good deed of the day has nowhere to go. |
+
+The chore shows a **✍️ Describe it** tag on the child's card so they know it behaves differently from a normal tick-box.
+
+---
+
+## What the Child Sees
+
+Tapping DONE opens a sheet instead of completing straight away:
+
+- **A description box.** This is required — it *is* the chore. Submitting with it empty is refused, in the card and in the service behind it.
+- **A points box.** What they reckon the job was worth. It is only ever a suggestion; it awards nothing on its own.
+
+The description is trimmed to 200 characters. Over-long text is shortened rather than rejected — losing the tail end of a sentence beats refusing a child's chore.
+
+---
+
+## Approval Is Always Required
+
+An open-ended completion goes to a parent **even when the chore has *Requires approval* switched off**. The child is the one naming the price, so it can never pay itself.
+
+This mirrors how [Photo Proof](Photo-Proof.md) behaves, and the two combine: with both switched on, the child is asked to describe the work first, then to take the photo, and the completion carries the description and the picture together.
+
+---
+
+## Reviewing and Pricing It
+
+In the [Approvals Card](Approvals-Card.md) each pending completion has a second control beside Approve — **✍️** when the child left a note, **✎** otherwise. It opens a review sheet with their words, the evidence photo if there is one, and an editable award already filled in with their suggestion.
+
+
+
+Change the number to whatever the job was actually worth and tap **Approve**.
+
+> **The award replaces the chore's base points, not the final total.** Streak and level multipliers still apply on top, exactly as they would for any other approval — so an open-ended approval behaves like a normal one rather than becoming a special case.
+
+Approving without opening the sheet still works as a single tap and awards the chore's own points.
+
+---
+
+## Doing It From an Automation
+
+The same three fields are on the services, so a script or automation can submit and price work without touching the cards.
+
+```yaml
+service: taskmate.complete_chore
+data:
+ chore_id: 8a3b2c1d4e5f6789
+ child_id: ef19c56175c14bd9
+ note: "I raked the leaves off the drive"
+ suggested_points: 15
+```
+
+```yaml
+service: taskmate.approve_chore
+data:
+ completion_id: 4f21b8e0c7a94d13
+ points: 12 # optional — omit to use the chore's own value
+```
+
+| Field | Service | Description |
+|-------|---------|-------------|
+| `note` | `complete_chore` | The child's description. Required when the chore is open-ended. Trimmed to 200 characters. |
+| `suggested_points` | `complete_chore` | Their own estimate, clamped to 0–999. A hint for the parent; awards nothing by itself. |
+| `points` | `approve_chore` | The award. Replaces the chore's base points; multipliers still apply. |
+
+See [Services](Services.md) for the full reference.
+
+---
+
+## Notifications
+
+The approval push quotes the child's estimate for an open-ended chore rather than the chore's own points, which for one of these is nearly always 0. See [Notifications](Notifications.md).
+
+---
+
+## Where It's Stored
+
+The description and the estimate live on the completion record as `note` and `suggested_points`. Both are only published on the pending-approvals sensor when they actually hold something, so ordinary tap-to-complete chores add nothing to the sensor's payload.
+
+---
+
+## Related
+
+- [Chores](Chores.md) — chore configuration and approvals
+- [Photo Proof](Photo-Proof.md) — the other switch that forces approval, and combines with this one
+- [Approvals Card](Approvals-Card.md) — where you review and price the submission
+- [Points Economy](Points-Economy.md) — how the award interacts with multipliers
+- [Services](Services.md) — full `complete_chore` and `approve_chore` reference
diff --git a/wiki/Parent-Access.md b/wiki/Parent-Access.md
new file mode 100644
index 00000000..72c945f0
--- /dev/null
+++ b/wiki/Parent-Access.md
@@ -0,0 +1,59 @@
+# Parent Access
+
+Give a second parent day-to-day control of TaskMate **without** making them a Home Assistant administrator.
+
+
+
+Added in v4.5.0.
+
+---
+
+## The problem this solves
+
+By default, every "parent" action in TaskMate — approving chores, adjusting points, confirming rewards — requires Home Assistant **admin** rights. Making a partner a full HA admin just to run the daily routine also gives them the ability to change unrelated Home Assistant configuration. The parent role closes that gap: it grants the day-to-day TaskMate controls and nothing more.
+
+## Privilege tiers
+
+| Tier | Who | Can do |
+|------|-----|--------|
+| **Admin** | Home Assistant admins | Everything, including the admin panel and all configuration. |
+| **Parent** *(new)* | Non-admin HA users you designate | Day-to-day actions only (see below). |
+| **Linked child** | An HA user linked to a child | That child's own self-service. |
+| **Kiosk** | Unlinked / shared tablet | Open child self-service. |
+
+## What a parent can do
+
+Straight from the TaskMate cards, a designated parent can:
+
+- Approve or reject chore completions — including **Approve All**
+- Approve or reject reward claims
+- Give, adjust or deduct points, gift points between children, and confirm allowance payouts
+- Apply a [bonus](Bonuses.md) or a [penalty](Penalties.md) to a child *(since v5.0.4)*
+- Award badges, and apply / postpone / dismiss mandatory-chore outcomes
+- Complete a chore on a child's behalf
+- Undo completions and approvals
+
+## What a parent cannot do
+
+- Open the TaskMate **admin panel** (`/taskmate-admin`) — it stays admin-only
+- Create or delete children
+- Edit chore, reward, badge, bonus or penalty **definitions** — applying an existing bonus or penalty is a daily action, but *defining* one is configuration
+- Change any settings, designs, or Home Assistant user links
+- Grant the parent role to anyone (only an admin can)
+
+Every parent action is recorded in the [Admin Audit Log](Admin-Audit-Log.md) against the parent's Home Assistant user, so there is always a trail of who did what.
+
+## Setting it up
+
+1. In Home Assistant, create a normal **non-admin** user for the parent (Settings → People → Users), if they don't already have one.
+2. Open the TaskMate admin panel → **[Settings](Settings.md)** → **Parents (no admin rights)**.
+3. Tick that user in the list (admins are omitted — they already have full access) and **Save**.
+4. Add the TaskMate cards to a dashboard the parent can reach. They will now see the parent controls (approve, reject, complete-on-behalf, adjust points) unlocked.
+
+To revoke, untick the user in the same place and Save.
+
+## How it works
+
+The role is a list of Home Assistant user IDs stored in TaskMate's settings. The backend enforces it on every day-to-day service call — a caller who is neither an admin nor a listed parent is rejected with `Unauthorized`, so hiding a control in the UI is never the only line of defence. The cards read the list from the `sensor.taskmate_overview` entity to decide which controls to show.
+
+See also [Child Undo Window](Child-Undo-Window.md) — an opt-in window in which children can undo their own chores.
diff --git a/wiki/Penalties.md b/wiki/Penalties.md
new file mode 100644
index 00000000..25b52d8d
--- /dev/null
+++ b/wiki/Penalties.md
@@ -0,0 +1,219 @@
+# Penalties
+
+The Penalties card lets parents apply named point deductions to children for unwanted behaviour — consistently and in one tap.
+
+
+
+
+Unlike the remove_points service which requires entering an amount each time, penalties are **named reusable definitions** (e.g. "Not going to bed — 10 Stars") that can be applied instantly without guessing an amount.
+
+---
+
+## Mandatory chore late penalties
+
+A separate kind of penalty comes from **mandatory chores**. A chore marked mandatory can carry a late penalty that applies if it isn't completed in time. TaskMate **never deducts these points automatically** — the missed chore is raised as a review item on the [Approvals Card](Approvals-Card.md), and the parent applies the penalty manually (or postpones/dismisses it). See [Mandatory Chores](Mandatory-Chores.md) for the full workflow.
+
+---
+
+## Make it right (v7.0.0)
+
+A penalty can name a **make-it-right** chore: when the penalty is applied, the child can do that chore within a set number of days and earn back some or all of the points. Losing points teaches less than putting right whatever went wrong ("tidy the mess you made").
+
+Set it in the penalty editor in the admin panel, under **Make it right**:
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Chore to earn it back** | None — no way back | The chore that repairs things. It is open to the child even on days it isn't normally due, until the offer runs out |
+| **Points back (%)** | `100` | How much of the deducted points comes back, 1–100 |
+| **Days to do it** | `1` | 1 = today only; up to 7 |
+
+The child card shows the offer ("Do “Tidy the playroom” by Friday to earn back 10"). The points come back when the chore is approved (or straight away if it needs no approval), and are taken back again if that chore is undone or rejected. These fields are set in the admin panel only; the `add_penalty` / `update_penalty` services don't take them. See [Make-It-Right Penalties](Make-It-Right-Penalties.md).
+
+---
+
+## Penalties Card
+
+```yaml
+type: custom:taskmate-penalties-card
+entity: sensor.taskmate_overview
+title: Penalties
+```
+
+**Config options:**
+
+| Option | Default | Description |
+|--------|---------|-------------|
+| `entity` | required | `sensor.taskmate_overview` |
+| `title` | `Penalties` | Card header title |
+
+---
+
+## Using the Card
+
+### Applying a Penalty
+
+1. If there are multiple children, tap the child's name tab at the top to select who to apply the penalty to
+2. Each penalty row shows its icon, name, description, and point cost
+3. Tap **Apply** — points are deducted immediately and a toast confirms the action
+4. The bottom of the card shows which child is currently selected
+
+> Penalties respect `assigned_to` — if a penalty is assigned to specific children, it only appears for those children's tabs.
+
+> **Who can apply one.** Home Assistant admins and [TaskMate parents](Parent-Access.md) see **Apply**; only admins see the manage controls, and anyone else sees the list read-only. Parents could not apply penalties before v5.0.4.
+
+### Managing Penalties (Edit Mode)
+
+Tap the **pencil icon** (top right) to enter edit mode:
+
+- **Add** — tap **New Penalty** to open an inline form with name, points, description, and icon fields
+- **Edit** — tap the edit icon on any penalty row to edit it inline
+- **Delete** — tap the trash icon to remove a penalty definition
+
+Changes are saved to the integration immediately — no separate save step.
+
+---
+
+## Penalty Fields
+
+| Field | Required | Default | Description |
+|-------|----------|---------|-------------|
+| `name` | Yes | — | Display name shown on the card |
+| `points` | Yes | — | Points to deduct when applied |
+| `description` | No | — | Optional explanation shown below the name |
+| `icon` | No | `mdi:alert-circle-outline` | MDI icon slug |
+| `assigned_to` | No | All children | List of child IDs — leave empty to show for all children |
+| `redemption_chore_id` | No | none | (v7.0.0, panel only) The [make-it-right](#make-it-right-v700) chore |
+| `redemption_percent` | No | `100` | (v7.0.0, panel only) Percent of the penalty given back, 1–100 |
+| `redemption_days` | No | `1` | (v7.0.0, panel only) Days the child has to do it, 1–7 |
+
+---
+
+## Services
+
+Penalties can also be managed and applied from automations, scripts, or Developer Tools.
+
+### `taskmate.add_penalty`
+
+Create a new penalty definition.
+
+| Parameter | Required | Description |
+|-----------|----------|-------------|
+| `name` | Yes | Display name |
+| `points` | Yes | Points to deduct when applied |
+| `description` | No | Optional explanation |
+| `icon` | No | MDI icon slug (e.g. `mdi:bed-clock`) |
+
+```yaml
+service: taskmate.add_penalty
+data:
+ name: "Not going to bed"
+ points: 10
+ description: "Refused bedtime after two warnings"
+ icon: mdi:bed-clock
+```
+
+---
+
+### `taskmate.update_penalty`
+
+Update an existing penalty. Only provided fields are changed.
+
+| Parameter | Required | Description |
+|-----------|----------|-------------|
+| `penalty_id` | Yes | ID of the penalty to update |
+| `name` | No | New name |
+| `points` | No | New point value |
+| `description` | No | New description |
+| `icon` | No | New MDI icon |
+
+```yaml
+service: taskmate.update_penalty
+data:
+ penalty_id: abc12345
+ points: 15
+```
+
+---
+
+### `taskmate.remove_penalty`
+
+Delete a penalty definition.
+
+| Parameter | Required | Description |
+|-----------|----------|-------------|
+| `penalty_id` | Yes | ID of the penalty to delete |
+
+```yaml
+service: taskmate.remove_penalty
+data:
+ penalty_id: abc12345
+```
+
+---
+
+### `taskmate.apply_penalty`
+
+Apply a penalty to a child. Points are deducted immediately and logged in the activity feed.
+
+| Parameter | Required | Description |
+|-----------|----------|-------------|
+| `penalty_id` | Yes | ID of the penalty to apply |
+| `child_id` | Yes | ID of the child to deduct from |
+
+```yaml
+service: taskmate.apply_penalty
+data:
+ penalty_id: abc12345
+ child_id: a8c8376a
+```
+
+---
+
+## Finding Penalty IDs
+
+Penalty IDs are in `sensor.taskmate_overview` under the `penalties` attribute:
+
+1. Go to **Developer Tools → States**
+2. Find `sensor.taskmate_overview`
+3. Expand the attributes and look for `penalties`
+4. Each entry has an `id` field — 8-character alphanumeric string
+
+---
+
+## Activity Log
+
+Every penalty application appears in the Activity Card with:
+- **Icon:** red shield
+- **Label:** Penalty name
+- **Points:** shown as a negative value (e.g. `−10`)
+
+---
+
+## Automation Example
+
+Apply a penalty automatically — for example when a motion sensor triggers after bedtime:
+
+```yaml
+automation:
+ trigger:
+ platform: state
+ entity_id: binary_sensor.bedroom_door
+ to: "on"
+ condition:
+ condition: time
+ after: "21:00:00"
+ action:
+ service: taskmate.apply_penalty
+ data:
+ penalty_id: abc12345
+ child_id: a8c8376a
+```
+
+---
+
+## Tips
+
+- **Keep penalties consistent** — named penalties mean the same behaviour always costs the same, which feels fairer to kids
+- **Use descriptions** — add context like "After three warnings" so there's no ambiguity about when the penalty applies
+- **Offer a way back** — a [make-it-right](Make-It-Right-Penalties.md) chore turns a penalty into something the child can fix
+- **Use `assigned_to`** — if you have children of different ages, assign age-appropriate penalties to specific children rather than showing all penalties for all children
diff --git a/wiki/Photo-Proof.md b/wiki/Photo-Proof.md
new file mode 100644
index 00000000..dc789046
--- /dev/null
+++ b/wiki/Photo-Proof.md
@@ -0,0 +1,98 @@
+# Photo Proof
+
+Photo proof lets a chore require evidence before it counts. When a chore has **Require photo proof** turned on, its completions always go through parent approval, and any photo attached to the completion is shown to the parent as a thumbnail in the approvals view.
+
+
+
+---
+
+## How It Works
+
+```
+Child completes chore (optionally with a photo) → Always pending → Parent reviews photo → Approve / Reject
+```
+
+- A chore with `require_photo` on **always** requires parent approval, even if **Requires Approval** is off. The evidence has to be reviewed before points are awarded.
+- The exception is completing on behalf of a child — a parent using the `as_parent` flag (see [Chores](Chores.md#completing-on-behalf-of-a-child)) auto-approves as normal, since the parent is already the one acting.
+
+---
+
+## Turning It On
+
+Enable **Require photo proof** in the chore dialog (add and edit) in the [Admin Panel](Admin-Panel.md). It is a simple on/off switch stored on the chore as `require_photo` (default off).
+
+---
+
+## Attaching a Photo
+
+A photo is attached at completion time via the `photo_url` field on the `taskmate.complete_chore` service. The value is a URL or path to an image — for example a camera snapshot captured by a Home Assistant automation.
+
+```yaml
+service: taskmate.complete_chore
+data:
+ chore_id: b3f9a12c
+ child_id: a8c8376a
+ photo_url: /local/snapshots/dishwasher.jpg
+```
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `chore_id` | Yes | The chore being completed |
+| `child_id` | Yes | The child completing it |
+| `photo_url` | No | URL/path to an evidence image |
+
+A common pattern is an automation that fires `camera.snapshot` to a file under `/config/www/` (served at `/local/...`), then calls `complete_chore` with that path as `photo_url`. The photo is optional even on a photo-required chore — the requirement forces *approval*, while the photo is the evidence the parent looks at when deciding.
+
+---
+
+## Where It's Stored
+
+The photo path is saved on the completion record as `photo_url` and persists with the completion in storage. It is not copied or re-hosted — TaskMate stores the reference you pass in, so the underlying file must remain reachable for the thumbnail to load.
+
+---
+
+## Reviewing During Approval
+
+A completion that carries a `photo_url` shows a small thumbnail next to the entry. Clicking it opens the full image in a new tab (a **View photo** link). Since v4.0.1 the thumbnail renders not only in the [Admin Panel](Admin-Panel.md) approvals list, but also on the [Approvals Card](Approvals-Card.md) and the [Parent Dashboard](Dashboard-Cards.md) card. The parent then approves or rejects as usual:
+
+- **Approve** → points are awarded
+- **Reject** → completion removed, no points
+
+> **Note:** Browsers don't send the Home Assistant bearer token on a plain ` ` request, so the sensor **signs the photo URL** (appending an `authSig` token) before handing it to the cards. This lets the evidence image load directly in the Approvals and Parent Dashboard cards without any extra authentication.
+
+---
+
+## Browsing Past Photos — the Photo Gallery Card
+
+To look back over evidence photos after they've been approved, add the **Photo Gallery Card** (`custom:taskmate-photo-gallery-card`). It shows a grid of thumbnails for every chore completion that carried a proof photo, each captioned with the child, the chore, and the date.
+
+```yaml
+type: custom:taskmate-photo-gallery-card
+entity: sensor.taskmate_activity
+title: Proof Photos # optional — custom card title
+max: 40 # optional — limit the number of photos shown
+header_color: "#5d6d7e"
+```
+
+- Tap a thumbnail to open the full image in a new tab.
+- Completions still awaiting approval are marked **pending** in their caption.
+- The grid is backed by the `photo_gallery` attribute on the activity sensor (`sensor.taskmate_activity`). As with the approvals views, each photo path is signed before display so the image loads without extra authentication.
+
+See [Dashboard Cards](Dashboard-Cards.md) for the full list of TaskMate cards.
+
+---
+
+## The Photo Reaches the Approval Push
+
+The submitted photo is attached to the approval notification, so a parent can see the work and approve from the lock screen.
+
+**Only `mobile_app.*` notify services carry the image** — it rides in the companion app's push payload. A persistent notification or a third-party bridge gets the text message without the picture.
+
+See [Notifications](Notifications.md#evidence-photos-in-the-approval-push).
+
+## Related
+
+- [Chores](Chores.md) — chore configuration, approvals, and completing on behalf
+- [Approvals-Card](Approvals-Card.md) — where the thumbnail appears for review
+- [Multi-Parent Approval Routing](Multi-Parent-Approval-Routing.md) — who receives the approval push
+- [Services](Services.md) — full `complete_chore` reference
diff --git a/wiki/Points-Economy.md b/wiki/Points-Economy.md
new file mode 100644
index 00000000..38cc9048
--- /dev/null
+++ b/wiki/Points-Economy.md
@@ -0,0 +1,146 @@
+# Points Economy
+
+TaskMate's points economy is more than chores in and rewards out. From v4.0.0 a set of **automatic point mechanics** run quietly in the background — paying interest on savings, optionally shrinking idle balances, and handing out the occasional surprise — plus a parent gate to reverse a mistake. This page is the hub for those mechanics.
+
+All of these are **opt-in** and configured in the **TaskMate** panel → **Settings**, under the **History & streaks** section of the Admin Panel.
+
+For the manual point-awarding systems (weekend multiplier, streaks, perfect week) see [Bonus Points](Bonus-Points.md). For child-to-child transfers see [Gifting Points](Gifting-Points.md).
+
+---
+
+## Savings Interest
+
+Children earn interest on the points they have saved, rewarding patience over impulse spending. Interest is paid through the normal points path, so it also counts as earned points and feeds XP.
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Savings interest** | `off` | on / off | Master toggle |
+| **Interest rate** (`Interest %` field) | `5` | 0–100 | Percentage of the current balance paid as interest |
+| **Period** (`Every`) | `weekly` | `weekly` / `monthly` | When interest is paid |
+
+**How it works:**
+
+- Paid on the period boundary — **weekly** pays every Monday, **monthly** pays on the 1st
+- Each child earns `round(balance × rate ÷ 100)` points on their current spendable balance
+- Children with a zero or negative balance, or whose interest rounds to 0, are skipped
+- The credit is logged in the activity feed as `Savings interest (+N%)` and fires a `taskmate_interest_paid` event
+- A guard stamp prevents paying twice on the same day
+
+**Set the rate to `0` or leave the toggle off to disable.**
+
+---
+
+## Points Decay
+
+The opposite lever to interest: idle balances slowly shrink, discouraging hoarding and keeping the economy moving. Decay only touches the **spendable balance** — it does **not** affect a child's career score or earned totals, so it is not a penalty.
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Points decay** | `off` | on / off | Master toggle |
+| **Decay %** | `10` | 0–100 | Percentage of the balance removed each period |
+| **Every** | `monthly` | `weekly` / `monthly` | How often decay runs |
+
+**How it works:**
+
+- Runs on the period boundary — **weekly** on Mondays, **monthly** on the 1st
+- Each child loses `round(balance × percent ÷ 100)` points; the balance never goes below 0
+- Logged in the activity feed as `Points decay (-N%)` and fires a `taskmate_points_decay` event
+- Children with a zero balance, or whose decay rounds to 0, are skipped
+- A guard stamp prevents decaying twice on the same day
+
+**Set the percentage to `0` or leave the toggle off to disable.**
+
+---
+
+## Surprise Bonus
+
+A random daily chance for each child to receive a surprise points bonus — a small dose of unpredictability that keeps things fun.
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Surprise bonuses** | `off` | on / off | Master toggle |
+| **Chance %** | `15` | 0–100 | Per-child chance of a bonus each day |
+| **Min pts** | `5` | ≥ 0 | Lower bound of the random award |
+| **Max pts** | `20` | ≥ 0 | Upper bound of the random award |
+
+**How it works:**
+
+- Rolled once a day at **16:00**
+- Each child is rolled independently against the chance percentage; on a hit they receive a random amount between Min and Max points
+- If Min is greater than Max the two are swapped automatically
+- Awarded through the normal points path, so it counts as earned and feeds XP
+- Logged in the activity feed as a surprise bonus and fires a `taskmate_surprise_bonus` event
+
+**Leave the toggle off to disable.** See also [Bonus Points](Bonus-Points.md).
+
+---
+
+## Negative Balances
+
+By default a child's balance can never drop below zero: if a penalty or deduction is larger than what they hold, the balance simply floors at **0** and only the points they actually had are taken. This keeps things simple for younger children — you can't owe points.
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Allow negative balance** | `off` | Let penalties take a child's balance below zero instead of stopping at zero |
+
+Turn **Allow negative balance** (`allow_negative_balance`) on if you'd rather a deduction takes the **full** amount even when it pushes the balance into the negative — modelling a small "debt" the child has to earn back before they're spending again. With it on, a 30-point penalty on a child holding 20 points leaves them at **−10** rather than **0**.
+
+This only changes how far a penalty can push the balance; everything else — career score, earned totals — is unaffected. The toggle lives alongside the other point mechanics in the Admin Panel settings.
+
+---
+
+## Per-Action Undo
+
+Applied the wrong penalty, awarded a bonus to the wrong child, or approved a chore by mistake? From v4.1.0 the **Activity card** puts a per-row **Undo (↩)** button on every reversible event. Tapping it opens a confirm dialog before anything changes.
+
+
+
+**What gets an Undo button:**
+
+| Event | Undoable? |
+|-------|-----------|
+| Applied penalty (`Penalty: …`) | ✅ |
+| Applied bonus (`Bonus: …`) | ✅ |
+| Manual points add / remove | ✅ |
+| Gift between children (both legs) | ✅ |
+| Chore completion / approval | ✅ — undo returns it to **pending** |
+| Weekend bonus | ❌ |
+| Streak-milestone / perfect-week bonuses | ❌ |
+| Pool allocations and refunds | ❌ |
+| Points decay | ❌ |
+| Savings interest | ❌ |
+| Badge awards | ❌ |
+
+Auto-derived events have no clean inverse, so undo is deliberately scoped to the discrete actions an admin (or child) took. The card's deny-list mirrors the backend, so the button simply never appears on a non-reversible row.
+
+**Behind the button**, two services do the work:
+
+- **Chore completions** call `taskmate.undo_chore_approval` with the `completion_id`. This removes the awarded points and returns the completion to **pending** so it can be approved again.
+- **Point transactions** (penalties, bonuses, manual adjustments, gifts) call `taskmate.undo_transaction` with the `transaction_id`. This restores the child's balance by the exact amount, rolls back the matching counter — `total_penalties_received` for a penalty, `total_points_earned` for a bonus — recomputes the career score, and removes the original transaction from the activity log.
+
+The action is **admin-gated** and recorded in the [Admin Audit Log](Admin-Audit-Log.md).
+
+```yaml
+# reverse a points transaction
+service: taskmate.undo_transaction
+data:
+ transaction_id:
+
+# revert a chore approval back to pending
+service: taskmate.undo_chore_approval
+data:
+ completion_id:
+```
+
+See [Dashboard Cards](Dashboard-Cards.md) for the Activity card and [Services](Services.md) for full parameter details.
+
+---
+
+## Related
+
+- [Bonus Points](Bonus-Points.md) — weekend multiplier, streak milestones, perfect week
+- [Gifting Points](Gifting-Points.md) — child-to-child point transfers
+- [Allowance](Allowance.md) — convert points into a real-money payout
+- [Rewards](Rewards.md) — spending caps and reward stock
+- [Settings](Settings.md) — full settings reference
+- [Services](Services.md) — service-call reference
diff --git a/wiki/Pool-Mode-(Savings-Jars).md b/wiki/Pool-Mode-(Savings-Jars).md
new file mode 100644
index 00000000..f86f6c76
--- /dev/null
+++ b/wiki/Pool-Mode-(Savings-Jars).md
@@ -0,0 +1,116 @@
+# Pool Mode (Savings Jars)
+
+> **Available in:** v3.0.0+
+> **Status:** Opt-in (per-reward or per-card)
+> **Breaking changes:** None
+
+
+
+Pool Mode transforms individual rewards from a "shared wallet" model into dedicated **savings jars**. Instead of every progress bar moving together when a child earns points, the child manually deposits points into one specific reward's jar.
+
+Wallet-mode rewards (the classic 2.x behaviour) and pool-mode rewards can coexist on the same card, so short-term treats and long-term goals live side by side.
+
+## Why use Pool Mode?
+
+- **Clear mental model for kids** — each progress bar represents dedicated effort toward one specific goal
+- **Teaches savings & commitment** — allocated points are locked; they can't be moved back once deposited
+- **Eliminates mental math** — children see "I have 12 spendable, my LEGO jar has 22/50" rather than calculating how spending 10 on candy delays the LEGO goal
+- **Mixed cards** — one rewards card can show a 10pt candy (wallet, instant-buy) and a 500pt LEGO (pool, savings goal)
+
+## Concepts
+
+| Term | Meaning |
+| --- | --- |
+| **Gross balance** (`child.points`) | Points the child holds after deposits have been subtracted |
+| **Spendable balance** | Gross balance minus points committed to pending claims |
+| **Allocated points** | Total the child has deposited across all pool-mode rewards |
+| **Pool** / allocation | Points a specific child has deposited into a specific reward |
+| **Redeem** | Once a pool is 100 % full, the child taps Redeem to request the reward |
+
+## Enabling Pool Mode
+
+### Recommended: per reward (TaskMate panel → Rewards)
+
+1. Open the **TaskMate** panel → **Rewards**
+2. Add a new reward, or edit an existing one
+3. Tick **"Pool Reward (Savings Jar)"**
+4. Save
+
+Rewards without the toggle continue in wallet mode. On the same card, pool rewards will show deposit buttons while wallet rewards still show the Claim button.
+
+### Per-card override
+
+Add `enable_pool_mode: true` to a rewards-card YAML to force *every* reward displayed on that card into pool mode, regardless of the per-reward flag. Useful for a single-purpose "savings goals" dashboard.
+
+```yaml
+type: custom:taskmate-rewards-card
+entity: sensor.taskmate_overview
+child_id:
+enable_pool_mode: true
+```
+
+## The workflow
+
+1. **Earn** — Child completes chores, their spendable balance grows
+2. **Deposit** — Child taps a quick-deposit button (`[+1]`, `[+5]`, `[+10]` by default) on a specific reward, or types any value into the **Amount** field for larger goals. The deposit immediately moves from spendable to that reward's allocation.
+3. **Save** — Deposits accumulate in the pool. Spendable balance drops; the targeted reward's bar grows; other rewards are untouched.
+4. **Redeem** — When the pool hits 100 %, an animated green **Redeem** button appears. Tap it to create a pending claim.
+5. **Approve** — Parent approves via the TaskMate Approvals card. The allocation clears; the reward is granted.
+
+### Customising the deposit buttons
+
+The quick-deposit buttons default to `[+1]`, `[+5]`, `[+10]`. Set the **Rewards card**'s `deposit_amounts` option to change them — handy for high-value goals:
+
+```yaml
+type: custom:taskmate-rewards-card
+entity: sensor.taskmate_overview
+deposit_amounts: [10, 50, 100]
+```
+
+The free-form **Amount** field is always available regardless of the quick buttons, and any deposit is capped to the child's spendable balance and the pool's remaining room.
+
+## Multi-child cards
+
+Pool Mode requires an **active child** to attribute deposits. Two common setups:
+
+### One card per child
+Recommended. Give each child their own rewards card with `child_id:` set to their own ID. Progress and deposit buttons show only for that child.
+
+### Jackpot rewards for shared goals
+For community savings goals (a family pizza night), create a reward with **Is Jackpot** enabled — jackpots are **always pool-mode**, so there's no separate Pool toggle to set (the editor hides it). Each assigned child has their own deposit buttons; the combined pool fills as children contribute. Any assigned child can tap Redeem when the pool fills; on approval each contributing child loses only their own share. This is how a goal no single child could afford is reached together.
+
+## Behaviour details
+
+### Allocations are locked
+There is no withdrawal. Once deposited, points stay in the pool until redeemed. This is by design — the feature is explicitly about commitment to a saved goal.
+
+### Rejecting a claim does not refund
+If a parent rejects a pool-mode Redeem, the allocation stays full and the child can tap Redeem again. This models *"not right now, ask me again later"*, not *"cancel the goal"*. To permanently cancel a pool, the parent must delete the reward (which clears allocations without refunding points).
+
+### Deposit amounts are silently capped
+A deposit is capped at whichever is lowest:
+- The requested amount (`+1`, `+5`, `+10`)
+- The child's current spendable balance
+- The pool's remaining capacity (`reward.cost − already_allocated`)
+
+No error is shown — you just get less than requested, if less was available.
+
+### Tooltips explain disabled buttons
+Hover a greyed-out deposit button to see why:
+
+| Tooltip | Meaning |
+| --- | --- |
+| *"Select a child to deposit"* | Card has no `child_id` and no child is selected |
+| *"Not enough spendable (X available)"* | Spendable balance is below the deposit amount |
+| *"Depositing…"* | Previous deposit is still in flight |
+
+## Backward compatibility
+
+Rewards without `pool_enabled: true` continue to behave exactly as in v2.4.x. No migration runs unless you actually make pool allocations. All existing card configs remain valid.
+
+## Related
+
+- [Managing Rewards](Managing-Rewards.md) — the admin form
+- [Services](Services.md) — the `taskmate.allocate_points_to_pool` service
+- [Sensor Attributes](Sensor-Attributes.md) — new pool-related fields
+- [FAQ](FAQ.md) — common questions
diff --git a/wiki/Pre-Reader-Mode.md b/wiki/Pre-Reader-Mode.md
new file mode 100644
index 00000000..c3f86088
--- /dev/null
+++ b/wiki/Pre-Reader-Mode.md
@@ -0,0 +1,67 @@
+# Pre Reader Mode
+
+A picture-only child card for children who can't read yet. No chore names, no numbers — a big icon, a row of stars for the points, and a huge tick when it's done.
+
+
+
+---
+
+## Turning It On
+
+```yaml
+type: custom:taskmate-child-card
+entity: sensor.taskmate_overview
+child_id:
+pre_reader: true
+pre_reader_labels: false # optional; adds the chore name back under each tile
+pre_reader_points: false # optional; shows the point value instead of the stars
+```
+
+It is a mode of the standard child card, not a separate card, so everything else about that card still applies.
+
+---
+
+## Key Points
+
+- **Chores now have a picture.** Set one per chore in the panel, next to the description. Without one, a tile falls back to the time-of-day icon — fine for a single chore, useless for telling "brush teeth" from "get dressed". If you turn this mode on, set the pictures.
+- **Points are shown as stars, not digits** — one to five, scaled from the chore's value. A four-year-old can count pictures long before they can read "15 points". Set `pre_reader_points: true` to show the number instead — see below.
+- Tiles are at least **128 px** with a large tap target.
+- **A done tile stays tappable**, so a mis-tap can be undone, exactly as on the standard card.
+- **Opt-in.** An existing dashboard never turns itself into pictures, and names stay off unless you ask for them with `pre_reader_labels`.
+- Works under **all six** [card design styles](Card-Design-Styles.md) — the tiles sit inside whichever design the card is using. Pairing it with **Accessible** is a sensible combination for a child who needs both.
+
+---
+
+## Showing the Point Value Instead
+
+The star row is deliberately lossy: it rounds and clamps to one to five, so a
+seven-point chore and an eight-point chore both draw four stars. That is the
+point for a pre-reader, but it means the tile disagrees with the totals shown
+everywhere else on the dashboard.
+
+`pre_reader_points: true` replaces the stars with the value itself — `+7`,
+drawn with your family's points icon:
+
+```yaml
+pre_reader: true
+pre_reader_points: true
+```
+
+Use it for a child who has outgrown counting stars but still wants the big
+pictures. It is off by default, so existing picture-mode dashboards keep their
+stars.
+
+---
+
+## Adding Labels Back
+
+`pre_reader_labels: true` puts the chore name back underneath each tile while keeping the big pictures and the reward row. This is the useful middle setting for a child who is *learning* to read — they get the picture to go on and the word to grow into.
+
+---
+
+## Related
+
+- [Dashboard Cards](Dashboard-Cards.md) — every Lovelace card TaskMate ships
+- [Routine Mode](Routine-Mode.md) — a guided one-task-at-a-time flow, which pairs well with this
+- [Chores](Chores.md) — setting a chore's picture and icon
+- [Card Design Styles](Card-Design-Styles.md) — including the Accessible style
diff --git a/wiki/Presence-Aware-Reminders.md b/wiki/Presence-Aware-Reminders.md
new file mode 100644
index 00000000..58ebd565
--- /dev/null
+++ b/wiki/Presence-Aware-Reminders.md
@@ -0,0 +1,83 @@
+# Presence Aware Reminders
+
+There's no point telling a child to tidy their room while they're at football practice. Link a child to their phone or person entity and TaskMate **holds their reminders while they're out**, then sends a single friendly nudge when they get home:
+
+> 🏠 You're home, Mia — 3 chores left today.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## Setting It Up
+
+### 1. Link the child to a presence entity
+
+**TaskMate panel → Children → Edit → Presence (for reminders)**
+
+Pick a `person.*` or `device_tracker.*` entity, usually the person entity for the child's phone. Leave it empty and nothing changes for that child.
+
+### 2. Turn on the "Arrived home" notification
+
+**TaskMate panel → Notifications → Arrived home**
+
+This is the nudge a child gets when they arrive. It's off by default. Its row has an **Only after being away for** box (default **30** minutes), so popping to the shop next door doesn't trigger a message.
+
+Holding reminders back works as soon as the presence entity is set. The Arrived home nudge is optional.
+
+---
+
+## While the Child Is Away
+
+The child counts as away whenever the entity's state is anything other than `home`, for example `not_home` or the name of a zone like `School`.
+
+| Notification | While away |
+|--------------|------------|
+| Bedtime reminder | Held |
+| Streak at risk | Held |
+| [Mandatory chore](Mandatory-Chores.md) reminders | Held |
+| Custom reminders addressed to that child | Held |
+| Good news (badges, level-ups, celebrations, all done) | **Always sent** |
+
+Held reminders are **not** replayed later. They're folded into the one Arrived home message instead, so the child doesn't come home to a backlog of pings.
+
+### Mandatory chore escalation
+
+The child's reminder stages still move forward while they're out (and are held), but the **parent alert waits**. The escalation stops before the parent stage until the child is home, then carries on normally. You won't be told a chore was missed just because your child was out when it came due. See [Reminder Escalation](Reminder-Escalation.md).
+
+---
+
+## When the Child Gets Home
+
+One Arrived home nudge is sent if **either** of these is true:
+
+- They were away for at least the **Only after being away for** time (default 30 minutes), **or**
+- At least one reminder was held while they were out, however short the trip.
+
+No nudge is sent if they have no chores left to do. The count uses the same list the child card shows.
+
+[Quiet hours](Quiet-Hours.md) still apply. An arrival during quiet hours sends nothing.
+
+---
+
+## A Broken Tracker Never Silences Reminders
+
+If the presence entity is `unavailable` or `unknown`, TaskMate treats the child as **home**. A phone with a flat battery or a tracker that's dropped off the network never switches reminders off. GPS jitter while the child is at home can't send a second nudge either.
+
+---
+
+## Presence vs. Availability
+
+Presence **only affects notifications**. The child's chores stay visible on their card while they're out, so they can still tick things off from wherever they are.
+
+If you want chores themselves to disappear while a child is away (at their other parent's house, for example), use the **Availability sensor** on the child instead. See [Vacation Mode](Vacation-Mode.md) and [Children](Children.md).
+
+---
+
+## Related
+
+- [Notifications](Notifications.md) — notification types and routing
+- [Reminder Escalation](Reminder-Escalation.md) — the mandatory-chore reminder ladder
+- [Quiet Hours](Quiet-Hours.md) — times when nothing is sent
+- [Children](Children.md) — editing a child
diff --git a/wiki/Printable-Weekly-Chart.md b/wiki/Printable-Weekly-Chart.md
new file mode 100644
index 00000000..d06b15af
--- /dev/null
+++ b/wiki/Printable-Weekly-Chart.md
@@ -0,0 +1,43 @@
+# Printable Weekly Chart
+
+A fridge-ready A4 chore chart with a box to tick against every task. For the households where the paper chart on the fridge was never really the problem — the tracking was.
+
+
+
+`taskmate/print/weekly_chart` returns a **standalone HTML page**. Open it in a tab and print. There are no external assets, so it prints identically offline.
+
+---
+
+## Options
+
+| Option | Values |
+|--------|--------|
+| `orientation` | `portrait` *(default)* or `landscape` |
+| `week_start` | An ISO date anywhere in the week you want. Defaults to this week. |
+| `title` | Heading text. Defaults to "This week". |
+
+Orientation is **your choice, not a guess**: two children with short names fit portrait comfortably, five need the width.
+
+---
+
+## Key Points
+
+- **Schedule only.** A paper chart can't know next Thursday's weather, so entity-driven gates aren't applied. A chart that quietly omitted a chore would be worse than one that lists a chore you end up not needing.
+- **Chores with no assignee appear for every child**; assigned ones only for theirs.
+- **Children with nothing assigned are left off entirely** rather than printing an empty row.
+- Chore names are HTML-escaped — they are user input landing in a document.
+
+---
+
+## Points Still Count in TaskMate
+
+The chart is a paper mirror, not a replacement. Ticking a box on the fridge doesn't award points; the chore still gets completed in TaskMate as usual. The footer on the printout says so, so a child doesn't think the paper is the system.
+
+---
+
+## Related
+
+- [Admin Panel](Admin-Panel.md) — where the chart is generated
+- [Chore Scheduling](Chore-Scheduling.md) — what determines which chores land on which day
+- [Weather-Aware Chores](Weather-Aware-Chores.md) — deliberately not applied to the printout
+- [Pre-Reader Mode](Pre-Reader-Mode.md) — the on-screen equivalent for a child who can't read
diff --git a/wiki/Quality-Ratings.md b/wiki/Quality-Ratings.md
new file mode 100644
index 00000000..06bf925f
--- /dev/null
+++ b/wiki/Quality-Ratings.md
@@ -0,0 +1,102 @@
+# Quality Ratings
+
+Not every "done" is equal. A bedroom that's genuinely spotless deserves more than one where everything was shoved under the bed. With **quality ratings** on, you give each approved chore **1 to 3 stars**, and the points scale with the rating.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## How It Works
+
+When you approve a chore, pick a rating first:
+
+| Rating | Pays (default) |
+|--------|----------------|
+| ★ | 75% of the points |
+| ★★ | 100% of the points |
+| ★★★ | 125% of the points |
+| *No rating* | 100%, the same as before |
+
+Picking a star is only a selection. Tap **Approve** to pay it. Tap the same star again to clear it.
+
+Because an unrated approval pays 100%, turning the feature on changes nothing until you actually pick a star.
+
+---
+
+## Turning It On
+
+**TaskMate panel → Settings → History & streaks**
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Quality ratings** | Off | Show the star picker when approving chores. |
+| **Star multipliers** | `0.75` / `1.0` / `1.25` | What each rating pays, as a multiple of the chore's normal points. |
+
+---
+
+## Where You Can Rate
+
+- **[Approvals card](Approvals-Card.md)**: a star picker on every pending chore, in every card design, and in the review sheet.
+- **TaskMate panel**: the same picker in the approval queue.
+- **Phone approval notification**: with ratings on, a chore approval push offers **★**, **★★**, **★★★** and **Reject** instead of Approve and Reject. Android shows three actions at most, so the ratings come first there.
+
+Reward claims are never rated.
+
+---
+
+## How the Points Are Worked Out
+
+The rating scales the chore's **base points**, the amount the child was promised when they submitted it. Streak and weekend bonuses are then added on top as usual. The result is rounded to the nearest whole point.
+
+**Example:** a 10-point chore rated ★★★ with the default multipliers pays 12.5, rounded to **13** before any streak or weekend bonus.
+
+### Changing the award by hand
+
+If you type a different number of points in the approvals card's review sheet, that exact number is paid and the rating is only recorded. Picking a star in the review sheet updates the points box first, so the number you confirm is always the rated one.
+
+### Undo and reject
+
+Undoing or rejecting a rated chore takes back exactly what the rating paid. Undo also clears the rating, so a re-approval is rated fresh.
+
+---
+
+## Seeing the Ratings
+
+- The **[Activity card](Dashboard-Cards.md)** shows the stars on rated completions.
+- **TaskMate panel → Insights → Quality** shows the average rating overall, per child and per chore, with a breakdown of how many of each star were given. Unrated approvals are left out of the averages rather than counted as ★★. See [Insights](Insights.md).
+
+---
+
+## Services
+
+`taskmate.approve_chore` and `taskmate.approve_all_chores` take an optional `rating` from `1` to `3`:
+
+```yaml
+action: taskmate.approve_chore
+data:
+ completion_id: f5548687
+ rating: 3
+```
+
+With quality ratings switched off, the `rating` field is ignored.
+
+The `taskmate_chore_approved` event includes `quality_rating` when a rating was given.
+
+---
+
+## Tips
+
+- **Explain the stars to your children first.** "Three stars means I didn't have to check anything."
+- **Keep ★ for "done, but not properly".** For "not done at all", reject it with a reason instead. See [Reject Reasons](Reject-Reasons.md).
+- **Adjust the multipliers** if 75% feels too harsh. `0.9` / `1.0` / `1.25` keeps the incentive while softening the downside.
+
+---
+
+## Related
+
+- [Approvals Card](Approvals-Card.md) — approving chores from a dashboard
+- [Reject Reasons](Reject-Reasons.md) — telling a child why a chore was sent back
+- [Insights](Insights.md) — the Quality view
+- [Points Economy](Points-Economy.md) — how points are calculated
diff --git a/wiki/Quantity-Chores.md b/wiki/Quantity-Chores.md
new file mode 100644
index 00000000..69e46a54
--- /dev/null
+++ b/wiki/Quantity-Chores.md
@@ -0,0 +1,96 @@
+# Quantity Chores
+
+Some jobs come in amounts, not just "done": read 20 pages, swim 10 lengths, practise for 15 minutes. A **quantity chore** asks the child how many they did, and pays the chore's points **per unit**. Reading 12 pages of a 1-point-per-page chore earns 12.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Setting Up a Quantity Chore
+
+**TaskMate panel → Chores → edit a chore**
+
+
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Count in (unit)** | empty | The unit, e.g. `pages`, `laps`, `minutes` (up to 30 characters). Setting it turns the chore into a quantity chore, and **Points** become points per unit. Leave it empty for an ordinary chore |
+| **Most per go** | `0` | The most one completion can count (up to 10,000). 0 = no cap, and then every completion needs a parent's approval |
+
+Quantity doesn't apply to [open-ended](Open-Ended-Chores.md) or [timed](Timed-Tasks.md) chores: those already have their own way of setting the points, so the unit is ignored on them.
+
+These fields are set in the panel; the `add_chore` and `update_chore` services don't take them.
+
+---
+
+## How Points Are Worked Out
+
+The chore's points are multiplied by the number of units, and the usual adjustments then apply as for any chore, such as the [difficulty](Difficulty-Tiers.md) multiplier and early or late timing.
+
+| Chore | Points | Child says | Earns |
+|-------|--------|-----------|-------|
+| Reading (pages, max 30) | 1 | 12 pages | 12 |
+| Swimming laps (laps, max 20) | 3 | 8 laps | 24 |
+| Piano practice (minutes, no cap) | 1 | 25 minutes | 25, after a parent approves |
+
+A number over **Most per go** is capped to it.
+
+---
+
+## Completing One
+
+### On the child card
+
+The chore shows a **🔢 pages: +1 each** tag. Tapping it opens the sheet above: a big number with **−** / **+** (or type it), the unit, what it's worth ("Worth +12") and the limit. **Done!** sends it.
+
+### On the routine card
+
+The [routine card](Routine-Mode.md) shows a **−** / **+** stepper with the unit under the chore, and the points update as the child counts. **Done** sends the number.
+
+
+
+### Everywhere else
+
+A tile or a single tap can't ask "how many?", so these leave quantity chores to the child card:
+
+- the [kiosk card](Kiosk-Mode.md) marks them to be finished on the child's own card
+- the [chore board](Dashboard-Cards.md) shows them but doesn't tick them off
+- the [sticker chart](Sticker-Chart-Card.md) leaves them off
+- [watch complications](Watch-Complications.md) and [voice commands](Voice-Assistants.md) point the child to their card
+
+A child can't complete a quantity chore without saying how many: TaskMate refuses it ("Say how many pages you did."), however the completion arrives. A parent ticking it off without a number counts it as 1.
+
+---
+
+## Approval
+
+A quantity chore follows the chore's normal approval setting, with one rule on top: **a chore with no cap (Most per go = 0) always goes to a parent for approval** when a child does it, because the child chose the number. Set a cap if you're happy for it to approve itself.
+
+Approvers see the amount on every completion: **🔢 12 pages** on the [Approvals card](Approvals-Card.md) and the parent dashboard card, and the points shown are the total.
+
+---
+
+## Service
+
+`taskmate.complete_chore` takes an optional `quantity` (0–10,000): how many units were done. It's required from a child on a quantity chore.
+
+```yaml
+action: taskmate.complete_chore
+data:
+ chore_id: 3648f6de211f44a7
+ child_id: 8e16ad66b23f404e
+ quantity: 12
+```
+
+In the chores sensor a quantity chore carries `quantity_unit` and, if set, `quantity_max`; completions carry `quantity`.
+
+---
+
+## Related
+
+- [Chores](Chores.md) — every chore field
+- [Open-Ended Chores](Open-Ended-Chores.md) — the child describes the job and suggests a price
+- [Timed Tasks](Timed-Tasks.md) — points by the minute with a real timer
+- [Estimated Minutes](Estimated-Minutes.md) — how long a chore takes
diff --git a/wiki/Quests.md b/wiki/Quests.md
new file mode 100644
index 00000000..e8101b1f
--- /dev/null
+++ b/wiki/Quests.md
@@ -0,0 +1,106 @@
+# Quests
+
+A quest is a chore chain — an ordered sequence of existing chores that a child works through one step at a time. Finishing the whole chain awards a bonus. Quests are great for routines you want done in order, like a full bedtime or morning sequence.
+
+
+
+---
+
+## How It Works
+
+A quest is built from chores you've already created. Each child has their own progress through the chain:
+
+```
+Step 1 chore approved → Step 2 unlocks → … → Final step approved → Bonus awarded
+```
+
+- A child advances **one step** each time the chore at their **current step** is completed and approved
+- Only the chore matching the current step advances the quest — completing a later chore early does nothing for the quest
+- Bonus sub-task completions don't count toward quest steps
+- Finishing the final step awards the quest's **bonus points**, fires a `taskmate_quest_completed` event, and triggers an epic [celebration](Celebrations.md)
+
+> Quests are built from existing chores, so create your chores first. See [Chores](Chores.md).
+
+---
+
+## Creating a Quest
+
+Quests are managed in the **Admin Panel → Quests** tab (TaskMate's sidebar panel). There's no Settings config flow for quests — add, edit, and delete them from the panel.
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Name** | — | Display name of the quest (required) |
+| **Description** | `""` | Optional description |
+| **Icon** | `mdi:map-marker-path` | MDI icon |
+| **Steps** | none | Ordered list of chore IDs — at least one required |
+| **Bonus points** | `25` | Points awarded on completing the whole chain |
+| **Assign to** | all children | Which children the quest applies to — leave empty for all |
+| **Repeatable** | `false` | When finished, progress resets so the child can run it again |
+| **Active** | `true` | Inactive quests don't track progress or award bonuses |
+
+In the quest dialog you tap chores to add them as steps, then use the ▲▼ controls to put them in the order they should be done.
+
+### Repeatable vs one-shot
+
+- **Repeatable on** — when a child finishes the chain, their progress resets to step 0 and they can run it again (the `times_completed` count keeps climbing)
+- **Repeatable off** — once finished, the quest stays complete for that child and won't re-trigger
+
+---
+
+## Sensor Attributes
+
+Each child's entry in the `sensor.taskmate_overview` `children` attribute carries a `quests` array. Each item describes that child's progress through one active quest assigned to them:
+
+| Field | Description |
+|-------|-------------|
+| `quest_id` | The quest's ID |
+| `name` | Quest name |
+| `icon` | Quest icon |
+| `total_steps` | Number of steps in the chain |
+| `step` | Steps completed so far (capped at `total_steps`) |
+| `done` | `true` once the final step is complete (non-repeatable) |
+| `times_completed` | How many times this child has finished the chain |
+| `bonus_points` | The bonus awarded on completion |
+| `next_chore_id` | The chore ID the child needs to do next (empty when done) |
+
+Only **active** quests assigned to the child appear in the array.
+
+---
+
+## Completion & Rewards
+
+When a child finishes the final step:
+
+- The **bonus points** are credited to their balance and logged as a `Quest complete: ` transaction
+- The bonus counts as earned points, so it also feeds the child's [XP and level](Levels-and-XP.md)
+- A `taskmate_quest_completed` event fires with `child_id`, `child_name`, `quest_id`, `quest_name`, `bonus`, and `timestamp`
+- An epic [celebration](Celebrations.md) is triggered
+
+---
+
+## Automation Example
+
+### Announce a completed quest
+
+```yaml
+alias: Announce quest completed
+triggers:
+ - trigger: event
+ event_type: taskmate_quest_completed
+actions:
+ - action: notify.family
+ data:
+ message: >
+ {{ trigger.event.data.child_name }} completed the quest
+ "{{ trigger.event.data.quest_name }}" (+{{ trigger.event.data.bonus }})!
+```
+
+---
+
+## Related
+
+- [Chores](Chores.md) — quests are chains of existing chores
+- [Challenges](Challenges.md) — time-boxed targets that refresh each period
+- [Levels and XP](Levels-and-XP.md) — quest bonuses feed XP
+- [Celebrations](Celebrations.md) — the epic moment fired on quest completion
+- [Admin Panel](Admin-Panel.md) — where quests are created and managed
diff --git a/wiki/Quiet-Hours.md b/wiki/Quiet-Hours.md
new file mode 100644
index 00000000..7b99b3fb
--- /dev/null
+++ b/wiki/Quiet-Hours.md
@@ -0,0 +1,66 @@
+# Quiet Hours
+
+Quiet hours let you set a per-child do-not-disturb window. While a child's local time is inside their window, TaskMate suppresses **that child's** notifications — so you don't ping them during school or after bedtime. Parent notifications are never affected.
+
+
+
+Added in v4.4.0.
+
+---
+
+## What Quiet Hours Do
+
+Each child can have a daily quiet-hours window defined by a start and end time. While the current local time falls inside that window:
+
+- **The child's notifications are held back** — any notification routed to that child (bedtime reminders, streak-at-risk alerts, mandatory nudges, and so on) is silently skipped for the duration of the window.
+- **Parents are unaffected** — quiet hours only gate child recipients. Parent recipients (and the underlying bus event) still fire as normal.
+
+Quiet hours are checked at send time against the Home Assistant local clock, so a notification that would otherwise fire is simply not delivered to a child who is inside their window.
+
+---
+
+## How the Window Works
+
+A window is two times in 24-hour `HH:MM` form:
+
+| Field | Description |
+|-------|-------------|
+| `quiet_hours_start` | Start of the window (inclusive), e.g. `20:00`. Empty = quiet hours disabled. |
+| `quiet_hours_end` | End of the window (exclusive), e.g. `07:00`. Empty = quiet hours disabled. |
+
+Rules:
+
+- **Both** times must be set. If either is empty, quiet hours are off for that child.
+- The **end is exclusive** — a notification at exactly the end time is allowed through. A window with equal start and end (e.g. `07:00`–`07:00`) is treated as disabled.
+- If the **start is later than the end**, the window is **overnight** — it runs from the start time, through midnight, to the end time the next morning. For example `20:00`–`07:00` covers every evening through to the following morning.
+- If the start is earlier than the end, it's a same-day window (e.g. `08:30`–`15:00` to stay quiet during the school day).
+
+---
+
+## Setting Quiet Hours
+
+Quiet hours are set per child in the **Admin Panel → Notifications** tab, alongside each child's notify service. Each child row has a **Quiet hours** start and end time picker — fill in both to enable the window, or clear them to turn it off.
+
+---
+
+## Example Windows
+
+| Use case | Start | End |
+|----------|-------|-----|
+| Quiet overnight (bedtime) | `20:00` | `07:00` |
+| Quiet during the school day | `08:30` | `15:30` |
+| Quiet over lunch only | `12:00` | `13:00` |
+
+---
+
+## Interaction with Escalation
+
+The mandatory-chore nudge (the first rung of [Reminder Escalation](Reminder-Escalation.md)) respects quiet hours too — because it is sent only to the affected child, it is held back while that child is inside their window. The parent alert at the top of the escalation ladder is a parent notification and is never suppressed.
+
+---
+
+## Related
+
+- [Children](Children.md) — the per-child fields, including quiet hours
+- [Notifications](Notifications.md) — the notification system that honours quiet hours
+- [Reminder Escalation](Reminder-Escalation.md) — the mandatory-chore nudge that respects quiet hours
diff --git a/wiki/Raffles.md b/wiki/Raffles.md
new file mode 100644
index 00000000..b606c972
--- /dev/null
+++ b/wiki/Raffles.md
@@ -0,0 +1,160 @@
+# Raffles
+
+Some prizes are too big to price as a reward: a trip to the trampoline park, a new game, choosing the takeaway. Put one up as a **raffle** instead. Children spend points on tickets, each ticket is one chance, and at the draw time one ticket is picked at random. The more tickets a child holds, the better their odds, but anyone with a ticket can win.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## How It Works
+
+1. **You set up a raffle** in the TaskMate panel: a prize, a fixed ticket price, an optional limit per child, and when it is drawn.
+2. **Children buy tickets** with their points on the Raffles card, as many as they like up to the limit.
+3. **At the draw time** TaskMate picks the winner. The chance of winning is weighted by tickets: a child holding 3 of 8 tickets has a 3 in 8 chance.
+4. **The winner is revealed** with a spinning draw on the Raffles card and the [kiosk](Kiosk-Mode.md), and the *Raffle drawn* notification goes out.
+5. **You hand over the prize.** The raffle doesn't pay any points; the prize is whatever you promised.
+
+Ticket prices never change once a raffle is open. There's no dynamic pricing: a ticket costs the same for the last buyer as for the first.
+
+---
+
+## Setting Up a Raffle
+
+**TaskMate panel → Raffles → New raffle**
+
+
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Name** | — | What the raffle is called, e.g. "Half-term mega raffle" |
+| **Prize** | — | What the winner gets, e.g. "Cinema trip" |
+| **Icon** | ticket | Any MDI icon |
+| **Ticket price** | — | Points per ticket (1–100,000). Fixed for the whole raffle: once anyone has bought a ticket the price can't change |
+| **Most tickets per child** | 0 | 0 = no limit. Otherwise up to 100 |
+| **Draw at** | — | When the winner is picked. Must be in the future |
+| **Applies to** | everyone | Which children can take part. Leave empty for every child |
+
+A raffle can be edited while it is open (apart from the price once tickets are sold). Drawn and called-off raffles can't be changed.
+
+---
+
+## The Raffles Page
+
+
+
+The **Raffles** page (under **Spend**) lists every raffle with its ticket price, who has bought how many tickets, and the result. Open raffles have three actions:
+
+| Action | What it does |
+|--------|--------------|
+| **Draw now** | Picks the winner straight away instead of waiting for the draw time |
+| **Call off** | Cancels the raffle and refunds every ticket in full |
+| **Edit** | Opens the raffle editor |
+
+Drawn and called-off raffles can be deleted. Deleting an open raffle that has tickets calls it off (and refunds everyone) first.
+
+---
+
+## Buying Tickets
+
+On the Raffles card, a child picks how many tickets with **−** / **+** and taps **Buy 3 for 30**. The card shows how many tickets they hold and their chance of winning ("You have 3 tickets · 38% chance").
+
+- Tickets can only be bought while the raffle is open and before its draw time.
+- A child can't go over the raffle's ticket limit ("That's your lot").
+- Points already promised to a reward waiting for approval can't be spent on tickets.
+- Each purchase is a normal points transaction ("Raffle tickets ×3: Half-term mega raffle") in the child's history.
+
+---
+
+## The Draw
+
+At the draw time (checked once a minute), or when you tap **Draw now**:
+
+- One ticket is picked at random. Every ticket has the same chance, so a child's odds are their share of all the tickets sold.
+- A raffle nobody entered closes with no winner ("Nobody entered").
+- Called-off raffles refund every ticket: "Raffle called off: Half-term mega raffle" appears in each child's history.
+
+Drawn and called-off raffles stay on the cards under **Recently drawn** for 24 hours, then leave the cards. They stay in the panel's list.
+
+### The reveal
+
+When a raffle has just been drawn, the Raffles card plays the draw: the names spin through, one for each ticket so the odds show, slow down and land on the winner. The winning child's own card says **You won! 🎉**.
+
+
+
+Each device plays a draw once, and only in the first few minutes after it.
+
+### On the wall tablet
+
+The [kiosk card](Kiosk-Mode.md#raffle-draws) spins the draw full-screen too, so the whole family can watch. It's on by default; turn off **Show raffle draws** in the kiosk card editor (`show_raffle_draws: false`) to skip it. When the kiosk sits idle in ambient mode showing the family's day, open raffles are listed there too.
+
+
+
+---
+
+## The Raffles Card
+
+**Edit dashboard → + Add Card → TaskMate Raffles**
+
+```yaml
+type: custom:taskmate-raffle-card
+entity: sensor.taskmate_overview
+child_id: 8e16ad66b23f404e # leave out for the family view
+```
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `entity` | string | **required** | The TaskMate overview sensor |
+| `child_id` | string | everyone | The child who buys tickets on this card. Leave it out (**Everyone** in the editor) for a family view on a shared screen: everyone's tickets, no buying |
+| `title` | string | `Raffles` | Card title |
+| `show_reveal` | boolean | `true` | Play the spinning draw when a raffle is drawn |
+| `card_design` | string | global default | `classic`, `playroom`, `console`, `cleanpro`, `accessible` or `graphite` |
+| `header_color` | string | `#8e44ad` | Header banner colour |
+
+A child's card only lists raffles open to that child.
+
+---
+
+## Notification and Events
+
+The **Raffle drawn** notification (off by default; switch it on under **Notifications**) announces the result: "🎟️ Half-term mega raffle: Vaiha won! (8 tickets in the draw)".
+
+| Event | When | Data |
+|-------|------|------|
+| `taskmate_raffle_drawn` | A raffle is drawn (fires even with the notification off) | `raffle_id`, `raffle_name`, `prize`, `winner_id`, `winner_name`, `tickets` (total sold) |
+| `taskmate_raffle_won` | A child wins | `child_id`, `child_name`, `raffle_id`, `raffle_name`, `prize`, `tickets` (the winner's) |
+
+On the [event entities](Event-Entities.md), the draw shows as **Raffle drawn** on the family entity and the win as **Raffle won** on the winner's entity.
+
+---
+
+## Services
+
+| Service | Who | Description |
+|---------|-----|-------------|
+| `taskmate.buy_raffle_tickets` | Child | Spend points on tickets: `raffle_id`, `child_id`, `tickets` (1–100) |
+| `taskmate.draw_raffle` | Parent | Draw a raffle now: `raffle_id` |
+
+Raffles are created, edited and called off in the panel. Open raffles, and ones drawn in the last day, are published as the `raffles` attribute of `sensor.taskmate_rewards`.
+
+---
+
+## Ideas
+
+| Raffle | Ticket price | Limit |
+|--------|-------------|-------|
+| Trip to the trampoline park | 10 | 10 each |
+| Pick the takeaway on Friday | 3 | none |
+| Stay up an hour late on Saturday | 5 | 5 each |
+| A new book of their choice | 8 | none |
+
+---
+
+## Related
+
+- [Rewards](Rewards.md) — fixed-price rewards children claim directly
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — saving up together for something big
+- [Kiosk Mode](Kiosk-Mode.md) — the draw on the shared wall tablet
+- [Notifications](Notifications.md) — switching on Raffle drawn
+- [Event Entities](Event-Entities.md) — automating on a draw
diff --git a/wiki/Reactive-Chores.md b/wiki/Reactive-Chores.md
new file mode 100644
index 00000000..aaa27f4e
--- /dev/null
+++ b/wiki/Reactive-Chores.md
@@ -0,0 +1,76 @@
+# Reactive Chores
+
+A reactive chore is one raised by an automation that must be done *now*: *"the washing machine finished — empty it within 30 minutes."* It carries a deadline, an optional speed bonus, and it disappears when the moment has passed.
+
+
+
+These are created from automations rather than the panel, because the whole point is that something in the house triggered them.
+
+---
+
+## Creating One
+
+Call `taskmate.add_chore` with `expires_in_minutes`:
+
+```yaml
+triggers:
+ - trigger: state
+ entity_id: sensor.washing_machine_status
+ to: "finished"
+actions:
+ - action: taskmate.add_chore
+ data:
+ name: Empty the washing machine
+ points: 10
+ assigned_to: [""]
+ requires_approval: false
+ expires_in_minutes: 30
+ speed_bonus_points: 5
+```
+
+| Field | Effect |
+|-------|--------|
+| `expires_in_minutes` | Deadline this many minutes from now. `0` means no deadline — an ordinary chore. Maximum 10080 (one week). |
+| `speed_bonus_points` | Extra points awarded if the chore is completed before the deadline. |
+
+---
+
+## How It Works
+
+- **A chore with a deadline is automatically one-shot.** It exists to be done now and never carries into tomorrow.
+- The child card shows a live **countdown badge** — amber, turning red under five minutes — with the speed bonus displayed alongside it.
+- **Beat the deadline** and `speed_bonus_points` is added on top of the normal award. This *stacks* with the early-bonus / late-penalty of `due_time` if the chore has one, and with the [Chore Roulette](Chore-Roulette.md) multiplier.
+- **Miss it** and the chore disappears and is soft-disabled. The sweep runs on the 30-second poll, so a 30-minute chore doesn't sit on the card until midnight looking live.
+
+---
+
+## Reacting to a Miss
+
+Expiry fires a `taskmate_chore_expired` event so an automation can nag, re-raise the chore, or just log it:
+
+| Field | Meaning |
+|-------|---------|
+| `chore_id` | The chore that expired |
+| `chore_name` | Its name |
+| `deadline_at` | When it was due |
+| `timestamp` | When the expiry was processed |
+
+```yaml
+triggers:
+ - trigger: event
+ event_type: taskmate_chore_expired
+actions:
+ - action: notify.mobile_app_phone
+ data:
+ message: "{{ trigger.event.data.chore_name }} wasn't done in time."
+```
+
+---
+
+## Related
+
+- [Chores](Chores.md) — the full list of chore fields
+- [Chore Roulette](Chore-Roulette.md) — the multiplier that stacks with a speed bonus
+- [Automations](Automations.md) — every TaskMate bus event, and the blueprint pack
+- [Services](Services.md) — the full `taskmate.add_chore` signature
+- [Routine Mode](Routine-Mode.md) — honours reactive deadlines automatically
diff --git a/wiki/Read-Aloud.md b/wiki/Read-Aloud.md
new file mode 100644
index 00000000..7fae38f6
--- /dev/null
+++ b/wiki/Read-Aloud.md
@@ -0,0 +1,78 @@
+# Read Aloud
+
+Speak a child's outstanding chores to a media player — *"Ella, you have three things left: make your bed, brush your teeth and pack your bag."*
+
+
+
+Useful on a kitchen speaker at the point in the morning when nobody is looking at a screen.
+
+---
+
+## Calling It
+
+```yaml
+action: taskmate.read_aloud
+data:
+ child_id:
+ media_player: media_player.kitchen # optional; falls back to the Settings default
+ tts_entity: tts.piper # optional; falls back to Settings, then the only one installed
+ message: "Dinner is ready" # optional; says this instead of the chore summary
+```
+
+| Field | Effect |
+|-------|--------|
+| `child_id` | Whose chores to read |
+| `media_player` | Where to speak. Falls back to the default in Settings. |
+| `tts_entity` | Which TTS engine. Falls back to Settings, then to the only one installed if there is just one. |
+| `message` | Speak this instead of the generated summary. |
+
+---
+
+## Wording
+
+The sentence comes from **parent-editable templates in Settings**, not from TaskMate's translations. The frontend locales don't reach the backend, and a family may well want phrasing that isn't one of the eight shipped languages — or simply their own turn of phrase.
+
+| Setting | Default | Placeholders |
+|---------|---------|--------------|
+| `read_aloud_template` | `{name}, you have {count} things left: {chores}.` | `{name}` `{count}` `{chores}` |
+| `read_aloud_one_template` | `{name}, you have one thing left: {chores}.` | same |
+| `read_aloud_done_template` | `{name}, you're all done. Nice one!` | same |
+| `read_aloud_joiner` | `and` | joins the last two chores |
+
+A template with a bad placeholder **logs a warning and falls back to the built-in wording** rather than silencing the feature. A typo in a sentence should not mean the speaker goes quiet with no explanation.
+
+---
+
+## Events
+
+Fires `taskmate_read_aloud` with `child_id`, `media_player`, `tts_entity` and `message`.
+
+---
+
+## Example Automation
+
+Read the morning list at 07:45 on school days:
+
+```yaml
+triggers:
+ - trigger: time
+ at: "07:45:00"
+conditions:
+ - condition: time
+ weekday: [mon, tue, wed, thu, fri]
+actions:
+ - action: taskmate.read_aloud
+ data:
+ child_id:
+ media_player: media_player.kitchen
+```
+
+---
+
+## Related
+
+- [Services](Services.md) — the full `taskmate.read_aloud` signature
+- [Voice Assistants](Voice-Assistants.md) — asking Assist about chores and points
+- [Settings](Settings.md) — the templates, default media player and TTS entity
+- [Notifications](Notifications.md) — the push side of the same job
+- [Localization](Localization.md) — why these templates are editable rather than translated
diff --git a/wiki/Ready-Made-Dashboards.md b/wiki/Ready-Made-Dashboards.md
new file mode 100644
index 00000000..ac7043f6
--- /dev/null
+++ b/wiki/Ready-Made-Dashboards.md
@@ -0,0 +1,73 @@
+# Ready Made Dashboards
+
+Don't want to build dashboards card by card? TaskMate can make a whole dashboard for each person in the house, filled in with your children, their colours and the right cards. It's saved once as an ordinary Home Assistant dashboard. After that it's yours: edit it, rearrange it, add your own cards, or delete it.
+
+
+
+> **New in v6.3.0**
+
+---
+
+## Where to Find It
+
+- **Settings.** **TaskMate panel → Settings → Ready-made dashboards.** Each preset has a tile with a **Create…** button.
+- **Command search.** Press **Ctrl K** and type "Create a dashboard".
+- **Setup wizard.** The [setup wizard](Setup-Wizard.md) has a **Dashboards** step with the same presets.
+
+Once a preset exists, its tile shows **Created** with an **Open** button. **Create…** is still there if you want a second copy at another address.
+
+---
+
+## The Presets
+
+| Preset | Address | What it creates |
+|--------|---------|-----------------|
+| **Kids** | `/taskmate-kids` | A tab for each child with their chores, reward goal, streak, badges and rewards, in the child's colour. A **Family** tab with the leaderboard and family goal |
+| **Parents** | `/taskmate-parents` | **Today**: approvals, the chore board and the parent dashboard. **Points**: points display, bonuses, penalties and leaderboard. **Insights**: weekly, graph, activity and calendar |
+| **Wall tablet** | `/taskmate-wall` | The [kiosk card](Kiosk-Mode.md) full screen, plus an optional chore board as a second tab |
+
+
+
+---
+
+## Creating One
+
+**Create…** opens a dialog where you set the title and the address. A **Preview** at the bottom lists every tab and card the dashboard will have, and it updates as you change the options.
+
+
+
+| Option | Presets | Default | What it does |
+|--------|---------|---------|--------------|
+| **Title** | all | Kids' chores / Parents / Chore wall | The name in the sidebar and the dashboard list |
+| **Address** | all | see above | Lower-case letters, numbers and dashes, with at least one dash |
+| **Children** | Kids | all children | Which children get a tab. Guest profiles are left out |
+| **Layout** | Kids | One dashboard, a tab each | **One dashboard, a tab each** suits a shared tablet: every child is a tab away. **A dashboard per child** suits a child's own phone: each child gets their own dashboard at the address followed by their name, e.g. `/taskmate-kids-malia` |
+| **Hide parent buttons** | Kids | on | Sets the cards' `show_parent_actions: false`, so nobody can approve, or complete a chore for a child, from these cards, even if a parent is signed in. See [Parent Access](Parent-Access.md) |
+| **Admins only** | Parents | off | Hides the dashboard from users who aren't Home Assistant admins. Leave it off if a parent isn't an admin; the cards still check parent rights before any action |
+| **Add a chore board tab** | Wall tablet | on | The whole family's day at a glance, one swipe away from the kiosk |
+| **Show in the sidebar** | all | on (off for Wall tablet) | Whether the dashboard appears in Home Assistant's sidebar |
+
+Tap **Create dashboard** and it's ready. The toast confirms it, and the tile changes to **Created / Open**.
+
+### It Never Overwrites
+
+Every address is checked before anything is written. If a dashboard or panel already uses one, the dialog says "Already in use: /taskmate-kids. Pick another address." and nothing is changed. With **A dashboard per child**, every child's address is checked first, so you never end up with half a set.
+
+---
+
+## Good to Know
+
+- **It's a starting point.** TaskMate doesn't keep a dashboard in sync once it's made. Add a child later and either add their tab by hand, or delete the dashboard and create it again.
+- **Badges cards point at each child's own badges sensor.** TaskMate looks the sensor up rather than guessing its name, so it keeps working with Home Assistant 2026.6+, which puts the device's area in front of new entity ids.
+- **Wall tablet tips.** The kiosk card fills the screen in a panel view. Its full-screen button hides the browser chrome. To also hide Home Assistant's sidebar and header, pair it with the *kiosk-mode* plugin from HACS. Turn on **Bounty Board** in the kiosk card's editor if you use [bounties](Bounty-Board.md).
+- **Card designs.** The cards follow your default [card design](Card-Design-Styles.md), and you can change any card's design afterwards in the dashboard editor.
+
+---
+
+## Related
+
+- [Setup Wizard](Setup-Wizard.md) — the Dashboards step
+- [Dashboard Cards](Dashboard-Cards.md) — every card and its options
+- [Kiosk Mode](Kiosk-Mode.md) — the wall tablet card
+- [Parent Access](Parent-Access.md) — what parents and children can do
+- [Card Design Styles](Card-Design-Styles.md) — the six designs
diff --git a/wiki/Recaps.md b/wiki/Recaps.md
new file mode 100644
index 00000000..ea42f023
--- /dev/null
+++ b/wiki/Recaps.md
@@ -0,0 +1,96 @@
+# Recaps
+
+A **recap** is a "Wrapped"-style story of a child's week, month or year: how many chores they did, the points they earned, their favourite chore, their longest streak, their best day, the badges and rewards they picked up, and how it compares with last time. Children tap through it like a story on their phone, and can save the last slide as a picture to share.
+
+
+
+> **New in v6.0.0.** Recaps are **off by default**. Nothing is built or sent until you choose how often you want them.
+
+---
+
+## Turning Recaps On
+
+**TaskMate panel → Settings → Recaps**
+
+
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Family default** | none ticked | Tick any mix of **Weekly**, **Monthly**, **Every 3 months**, **Every 6 months**, **Every 9 months** and **Yearly**. None ticked means recaps are off. The next date for each appears underneath |
+| **Per child** | Family default | Switch a child to **Custom** to give them their own mix. Younger children often enjoy weekly; teenagers may only want yearly |
+| **Notify when ready** | on / on | Whether the *Recap ready* notification goes to the child's device, to parents (as one grouped message), or both |
+| **Send at** | `08:00` | Recaps are built just after midnight; the notification waits until this time so nobody is woken up |
+| **Keep recaps for** | Forever | 1 year, 2 years or forever. Older recaps are deleted automatically |
+| **Compare with previous period** | on | Adds a "vs last time" slide |
+| **Preview** | — | Pick a child and build a throw-away recap of their last 30 days, to see what they'll get. It shows on their Recap card for a day, is never announced, and never counts as a "last time" to compare with |
+
+The first time you turn recaps on, the *Recap ready* notification is switched on and routed to every child and parent. After that, your own routing in **Notifications** wins: switch it off and it stays off.
+
+### When recaps are built
+
+- **Periods follow the calendar.** Monthly is a calendar month; every 3 and 6 months follow quarters and halves of the year; yearly is the calendar year. Weekly starts on the first day of the week for the country set in Home Assistant (Monday, Sunday or Saturday). Every 9 months counts from 1 January 2026.
+- **No back-filling.** Switching a frequency on never builds old recaps. The first one covers the period you switched it on in.
+- **Missed boundaries are caught up.** If Home Assistant was off at midnight, the recap is built when it starts again.
+- **Several at once.** When a month, a quarter and a year all end on the same day, all three arrive together and the longest one plays first.
+
+---
+
+## Watching a Recap
+
+Add the **Recap** card to each child's dashboard. The newest unwatched recap opens first.
+
+- **Tap** the right two-thirds of the story to go forward, the left third to go back. Arrow buttons and keyboard arrows work too.
+- **Older ▾** lists every recap that has been kept, filterable by frequency. Ones not yet watched on this device carry a **NEW** badge, and the next upcoming recap is shown locked.
+- The final slide has **Save as image**, which makes a picture with the child's name on it (using the share sheet where the device supports it), and **Again** to replay.
+
+Slides with nothing to show are skipped, so a quiet week doesn't end up with an empty "badges" slide.
+
+| Slide | Shows |
+|-------|-------|
+| Intro | The child's name and the period |
+| Chores done | The total, with a bar per day, week or month |
+| Points earned | From chores and bonuses |
+| Top chore | The one they did most |
+| Longest streak | Their best run of days in the period |
+| Best day | The day with the most chores, and a weekday chart |
+| Badges and rewards | What they earned and redeemed |
+| Compared with last time | Up or down on the previous period of the same length |
+| Finale | Save as image and Again |
+
+---
+
+## The Card
+
+```yaml
+type: custom:taskmate-recap-card
+entity: sensor.taskmate_overview
+child_id: 8e16ad66b23f404e
+```
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `entity` | string | `sensor.taskmate_overview` | The TaskMate overview sensor |
+| `child_id` | string | **required** | Whose recaps the card shows. Find IDs in the panel with **Show IDs** switched on |
+| `title` | string | `'s Recap` | Card header title |
+| `default_frequency` | string | newest | Which recap opens when there's nothing new: `weekly`, `monthly`, `every_3_months`, `every_6_months`, `every_9_months` or `yearly`. Leave it out for the newest |
+| `autoplay` | boolean | `false` | Move to the next slide every few seconds. Off: children tap at their own pace |
+| `card_design` | string | global default | `classic`, `playroom`, `console`, `cleanpro`, `accessible` or `graphite` |
+| `header_color` | string | `#9b59b6` | Header banner colour |
+
+A child only ever sees their own recaps, unless the dashboard's account is allowed to act for other children too. See [Parent Access](Parent-Access.md).
+
+---
+
+## Notification and Event
+
+- **Recap ready** — one push per child ("Your August recap is ready, Malia! Tap to watch it.") and one grouped message for parents, at the send time. The push carries no stats and no picture. Child [quiet hours](Quiet-Hours.md) are respected.
+- **`taskmate_recap_ready`** fires once per child whenever new recaps are ready, even if the notification is switched off. It carries `child_id`, `child_name`, `count` and the list of `recaps`.
+
+---
+
+## Related
+
+- [Insights](Insights.md) — the parent-facing reports: fairness, friction and the week ahead
+- [Weekly Digest](Weekly-Digest.md) — a weekly summary notification for parents
+- [Achievement Badges](Achievement-Badges.md) — what shows up on the badges slide
+- [Notifications](Notifications.md) — routing the *Recap ready* notification
diff --git a/wiki/Reference-Photos.md b/wiki/Reference-Photos.md
new file mode 100644
index 00000000..8b67417f
--- /dev/null
+++ b/wiki/Reference-Photos.md
@@ -0,0 +1,60 @@
+# Reference Photos
+
+Is the bed made, or just "made"? Give a chore a **reference photo**: a picture of the job done properly. When the child sends their evidence photo, you see the two side by side as you approve, so judging it takes a glance. It also helps children: "done" means looking like the picture.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Adding a Reference Photo
+
+**TaskMate panel → Chores → edit a chore → Reference photo → Upload**
+
+
+
+Upload a picture of the job done well (a tidy bedroom, a properly loaded dishwasher). **Remove** takes it off again. It's stored with TaskMate's other chore pictures and cleaned up when it's replaced, removed or the chore is deleted.
+
+It works best on chores with [photo proof](Photo-Proof.md) switched on, but it's shown on any chore that needs approval: with no evidence photo, you compare it with the real thing.
+
+The reference photo is set in the panel only; the `add_chore` and `update_chore` services don't take it.
+
+---
+
+## When You Approve
+
+### Approvals card
+
+A completion of a chore with a reference photo shows two thumbnails: the reference, marked with a gold ★, and the child's photo.
+
+
+
+Tap either thumbnail to open them **side by side**, labelled **★ What good looks like** and **📷 What was done**, as in the picture at the top of this page.
+
+The **review sheet** (the ✎ button, where you can change the points before approving) shows the pair too, above the award box:
+
+
+
+If the child sent no photo, tapping the reference opens it on its own with the note "No photo was sent — compare it with the real thing."
+
+This works in every card design.
+
+### Parent dashboard card
+
+The [parent dashboard card](Dashboard-Cards.md) shows the reference photo, marked with a ★, next to the evidence photo on each pending completion. Tap it to view it full size.
+
+---
+
+## Privacy
+
+Reference photos are chore pictures, not photos of your children, and are served the same way as chore pictures. They are left out of the [diagnostics download](Repairs-and-Diagnostics.md#diagnostics).
+
+---
+
+## Related
+
+- [Photo Proof](Photo-Proof.md) — evidence photos from children
+- [Approvals Card](Approvals-Card.md) — reviewing completions
+- [Quality Ratings](Quality-Ratings.md) — rating how well a job was done
+- [Chores](Chores.md) — every chore field
diff --git a/wiki/Reject-Reasons.md b/wiki/Reject-Reasons.md
new file mode 100644
index 00000000..393030d0
--- /dev/null
+++ b/wiki/Reject-Reasons.md
@@ -0,0 +1,93 @@
+# Reject Reasons
+
+A rejected chore with no explanation just leaves a child confused. When you reject a chore or a reward claim, you can now say **why**, and the child sees the reason on their card: "Sent back: Not finished".
+
+
+
+> **New in v6.0.0**
+
+---
+
+## Giving a Reason
+
+Tapping **Reject** now opens a small sheet instead of rejecting straight away:
+
+- **Quick-pick chips:** *Not finished*, *Needs redoing*, *Not today*. Tap one to fill in the reason.
+- **Free text:** type your own reason, up to 200 characters.
+- **Cancel** or **Reject** to confirm.
+
+The reason is **optional**. Leave the box empty and the reject works exactly as it always has.
+
+### Where you can reject with a reason
+
+| Where | Covers |
+|-------|--------|
+| **[Approvals card](Approvals-Card.md)** | Chores and reward claims, in every card design |
+| **TaskMate panel** | The approval queue on the Today page, the Activity tab and bounty rows |
+| **Phone approval notification** | **Reject** now opens a text box on the notification itself. Type a reason, or send it empty for a plain reject. |
+
+The quick-pick chips are in your family's language, so the reason the child sees is too. The quick reject on the parent dashboard card still rejects without a reason.
+
+---
+
+## What the Child Sees
+
+
+
+| Where | Shows |
+|-------|-------|
+| **Child card** | "Sent back: …" on the rejected chore, in every card design. |
+| **Rewards card** | "Not approved: …" on the reward, when the card is set to a child. |
+| **Activity card** | A *chore rejected* or *reward rejected* entry with the reason, under the Chores or Rewards filter. |
+
+The note on the child card disappears once the child does the chore again, once it's done, or after **24 hours**, whichever comes first.
+
+### Item rejected notification
+
+Turn on the **Chore or reward sent back** notification type under **TaskMate panel → Notifications** to tell the child straight away:
+
+> ↩️ Mia, "Tidy your room" was sent back: Not finished
+
+It's off by default. With no reason given, the message simply ends at "was sent back".
+
+---
+
+## Services
+
+`taskmate.reject_chore` and `taskmate.reject_reward` take an optional `reason`:
+
+```yaml
+action: taskmate.reject_chore
+data:
+ completion_id: f5548687
+ reason: The bed still isn't made
+```
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `reason` | No | Up to 200 characters, kept to one line. Leave it out for a plain reject. |
+
+The `taskmate_chore_rejected` and `taskmate_reward_rejected` events now carry `reason`. A child undoing their own chore (see [Child Undo Window](Child-Undo-Window.md)) fires `taskmate_chore_undone` instead, which never has a reason.
+
+---
+
+## How Long Reasons Are Kept
+
+Rejecting removes the completion or claim, so the reason is stored in a small log of its own. Entries are kept for **7 days** (50 at most) and are removed along with the child if you delete them. A reject without a reason adds nothing to it.
+
+---
+
+## Tips
+
+- **Be specific.** "The bed isn't made" gets a better second attempt than "Not finished".
+- **Use *Not today*** for chores that were fine but done on the wrong day.
+- **Done, but not very well?** With [Quality Ratings](Quality-Ratings.md) switched on, you can approve it with ★ instead of rejecting it.
+
+---
+
+## Related
+
+- [Approvals Card](Approvals-Card.md) — reviewing chores from a dashboard
+- [Rewards](Rewards.md) — reward claims and approval
+- [Quality Ratings](Quality-Ratings.md) — rating approved chores
+- [Notifications](Notifications.md) — notification types
diff --git a/wiki/Reminder-Escalation.md b/wiki/Reminder-Escalation.md
new file mode 100644
index 00000000..0725721e
--- /dev/null
+++ b/wiki/Reminder-Escalation.md
@@ -0,0 +1,64 @@
+# Reminder Escalation
+
+When a mandatory chore is left incomplete, TaskMate can step up its reminders over time instead of staying silent until the parent reviews the miss. The escalation ladder gives the child a gentle nudge first, reminds them again a while later, and finally alerts a parent if the chore is still not done.
+
+
+
+Added in v4.4.0.
+
+---
+
+## The Escalation Ladder
+
+Each open same-day [mandatory miss](Mandatory-Chores.md) climbs a three-rung ladder based on how long it has gone unresolved:
+
+| Stage | What fires | Audience | When |
+|-------|------------|----------|------|
+| 1 — Nudge | `mandatory_reminder` | The child | As soon as the miss is raised |
+| 2 — Reminder | `mandatory_reminder` | The child | After the **reminder** threshold |
+| 3 — Parent alert | `mandatory_parent_alert` | Parents | After the **parent** threshold |
+
+The child rungs (stages 1 and 2) are sent **only to the affected child**, not fanned out to every routed recipient. The parent alert goes to the parent recipients you have routed for it.
+
+If the child completes the chore at any point, that miss stops climbing the ladder.
+
+TaskMate re-evaluates open misses on a short periodic tick (roughly every five minutes), so a chore that crosses a threshold is escalated promptly without any automation of your own. Only **same-day** misses are escalated.
+
+---
+
+## Configuring the Thresholds
+
+Two thresholds, both in minutes, control when stages 2 and 3 fire. They are measured from the moment the miss was raised:
+
+| Setting | Default | Meaning |
+|---------|---------|---------|
+| `mandatory_escalation_reminder_minutes` | `30` | Minutes after the miss before the **second** child reminder fires |
+| `mandatory_escalation_parent_minutes` | `120` | Minutes after the miss before the **parent alert** fires |
+
+Set both in the **Admin Panel → Notifications** tab, under the mandatory-reminder controls (**"Remind again after"** and **"Alert parent after"**). Each accepts a value from **1 to 1440** minutes.
+
+---
+
+## Enabling the Notifications
+
+The two notification types are **off by default**. To use escalation, enable them in the **Admin Panel → Notifications** tab and route them to the right recipients:
+
+1. Enable the **Mandatory reminder** type and route it to the children who should receive nudges.
+2. Enable the **Mandatory parent alert** type and route it to the parent recipients who should be alerted.
+
+Each stage is gated by its own master toggle and routing — stages still advance internally even when a type is disabled, so re-enabling a type later won't retro-fire skipped reminders.
+
+---
+
+## Quiet Hours
+
+The child nudge and reminder respect [Quiet Hours](Quiet-Hours.md): because they are sent only to that child, they are held back while the child is inside their do-not-disturb window. The parent alert is a parent notification and is never suppressed by a child's quiet hours.
+
+---
+
+## Related
+
+- [Mandatory Chores](Mandatory-Chores.md) — how a miss is detected and reviewed
+- [Notifications](Notifications.md) — the notification system and routing
+- [Quiet Hours](Quiet-Hours.md) — the per-child do-not-disturb window the nudge respects
+- [Presence-Aware Reminders](Presence-Aware-Reminders.md) — hold reminders while a child is out, and the parent alert until they're home
diff --git a/wiki/Repairs-and-Diagnostics.md b/wiki/Repairs-and-Diagnostics.md
new file mode 100644
index 00000000..94785abb
--- /dev/null
+++ b/wiki/Repairs-and-Diagnostics.md
@@ -0,0 +1,90 @@
+# Repairs and Diagnostics
+
+TaskMate now uses two standard Home Assistant tools to help when something isn't working. **Repairs** tell you when part of your setup can't work any more (a phone removed from the Mobile App, a renamed entity, a chore left assigned to nobody) in the place Home Assistant users already check. The **diagnostics download** gives you a file to attach to a bug report that shows how TaskMate is configured without saying who your family are.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Repairs
+
+TaskMate's issues appear under **Settings → System → Repairs**, alongside any from Home Assistant itself, and the Settings menu shows a badge while there are any. Each one says what's wrong and where to fix it in the TaskMate panel.
+
+
+
+There's nothing to click to "fix" in the repair itself: make the change it describes and the issue **clears itself** on TaskMate's next update. **Ignore** hides one you don't want to deal with.
+
+### What's checked
+
+| Repair | Severity | Raised when |
+|--------|----------|-------------|
+| **TaskMate can't send notifications to {who}** | Warning | A notify service TaskMate is set to use no longer exists: the old global notify setting, any parent recipient that's switched on, or a child's own notify service. Usually a phone removed or renamed in the Mobile App integration. Fix under **Notifications** |
+| **{Child}'s profile uses a missing entity** | Warning | A child's availability, unavailability, presence or picture entity no longer exists, so the feature relying on it won't work. Fix under **Children** |
+| **"{Chore}" uses a missing entity** | Warning | An enabled chore's visibility or weather entity no longer exists, so that check is skipped. Fix under **Chores** |
+| **The chore "{Chore}" is assigned to nobody** | Warning | Every child an enabled chore was assigned to has been removed, so nobody will ever see it. Assign it or delete it under **Chores** |
+| **The chore "{Chore}" can never unlock** | Error | An enabled chore [depends on](Chore-Dependencies.md) a chore that has been deleted, so it stays locked for ever. Remove the missing dependency under **Chores** |
+| **No child can claim the reward "{Reward}"** | Warning | Every child a reward was meant for has been removed. Choose who it's for, or delete it, under **Rewards** |
+| **The reward "{Reward}" unlocks nothing** | Warning | A reward is set to switch on an entity that isn't on TaskMate's [unlock allowlist](Timed-Unlock-Rewards.md) any more, so nothing happens when it's approved. Add it back under **Settings**, or edit the reward |
+
+Each problem is raised once, however often it's checked: one repair per notify service, per chore or per reward, never a pile of duplicates. Disabled chores aren't checked.
+
+### When checks run
+
+Checks start once Home Assistant has finished starting and TaskMate has been loaded for two minutes. Notify services and entities from other integrations can take a while to appear after a restart, and a repair that flashed up at every boot would be worse than none. After that, every TaskMate update re-checks. Unloading TaskMate removes all its repairs.
+
+The panel's **Insights → Health** page still gives the full picture of your setup on demand; repairs are for the things that need attention now.
+
+---
+
+## Diagnostics
+
+**Settings → Devices & services → TaskMate → ⋮ → Download diagnostics**
+
+
+
+This downloads a JSON file to attach to a bug report on GitHub. It describes how TaskMate is set up, which is what's needed to reproduce most problems, and leaves out anything that says who your family are.
+
+
+
+### What's in it
+
+| Section | Contents |
+|---------|----------|
+| Versions | TaskMate and Home Assistant versions |
+| Entry | The config entry's version and options (its title is redacted) |
+| Entities | How many TaskMate entities there are, by platform |
+| Status | Whether TaskMate is loaded and its last update succeeded |
+| Health | The same health report as **Insights → Health** |
+| History sizes | How many completions, reward claims, points transactions, awarded badges, audit log entries, allowance payouts, mandatory misses, career score history entries, daily progress entries, recaps, moods and help requests are stored. **Only the counts**, never the records |
+| Settings | Every TaskMate setting, with personal values redacted |
+| Children | Each child's configuration and counters, with the ID kept so it lines up with chores' `assigned_to` |
+| Chores and rewards | Their configuration **with names kept** ("the Bins chore never shows" is what a bug report is usually about) |
+| Notifications | The notification configuration, with targets redacted |
+
+### What's left out
+
+These are replaced with `**REDACTED**` wherever they appear:
+
+- children's names, and every other name except chore and reward names
+- linked Home Assistant users and parent user IDs
+- notify services (who gets pushes, and on which phone)
+- picture, presence, availability and unavailability entities
+- birthdays
+- photos: evidence photo URLs, chore and reward pictures, [reference photos](Reference-Photos.md)
+- descriptions, notes and reasons
+- calendar subscription tokens, kiosk PINs and NFC tag IDs
+
+History itself (completions, transactions, moods, help requests and so on) is never included, only how many there are.
+
+Have a look through the file before you share it; it's plain JSON.
+
+---
+
+## Related
+
+- [Troubleshooting](Troubleshooting.md) — common problems and fixes
+- [Insights](Insights.md) — the Health page
+- [Notifications](Notifications.md) — notify services and recipients
+- [Chore Dependencies](Chore-Dependencies.md)
diff --git a/wiki/Rewards.md b/wiki/Rewards.md
new file mode 100644
index 00000000..77ad4146
--- /dev/null
+++ b/wiki/Rewards.md
@@ -0,0 +1,139 @@
+# Rewards Card
+
+
+
+
+The TaskMate Rewards Card displays available rewards as a vertical list with cost badges, progress bars, and claim/redeem buttons. Children use it to claim regular rewards or (from v3.0) deposit points into savings-jar rewards.
+
+## Adding the card
+
+In any Lovelace dashboard: **Edit → + Add Card → Custom: TaskMate Rewards Card**. The card editor uses native Home Assistant form components.
+
+Or via YAML:
+
+```yaml
+type: custom:taskmate-rewards-card
+entity: sensor.taskmate_overview
+```
+
+## Configuration
+
+| Option | Type | Default | Description |
+| --- | --- | --- | --- |
+| `entity` | string | **required** | The TaskMate overview sensor, usually `sensor.taskmate_overview` |
+| `title` | string | `"Rewards"` | Card title displayed in the header |
+| `child_id` | string | _none_ | If set, pin the card to this child (only their rewards, their interactions). If omitted, the card shows a **child picker** at the top so you can choose who is claiming/depositing — it defaults to the first child, so claim and deposit buttons work out of the box |
+| `show_child_badges` | boolean | `true` | Show which children can claim each reward as small badges |
+| `enable_pool_mode` | boolean | `false` | (v3.0+) Force all rewards on this card into Pool Mode, overriding per-reward flags |
+| `header_color` | string | `#e67e22` | Card header background colour |
+
+## Display
+
+Each reward row shows:
+
+- **Cost badge** (left): points icon + cost number
+- **Reward name and optional description**
+- **Progress bar** — for wallet rewards: child's points / cost. For pool rewards: allocated / cost.
+- **Child badges** (if `show_child_badges: true` and not a jackpot): small chips showing which children this reward is assigned to
+- **Quantity badge** (if limited stock): shows remaining count. Displays **Sold Out** when 0.
+- **Expiry indicator** (if expiration date set): shows days remaining or **Expired**.
+- **Action area** (right): Claim button (wallet) or deposit buttons `[+1] [+5] [+10]` (pool). When a pool fills, an animated green **Redeem** button replaces the deposits.
+
+### Spendable balance banner (Pool Mode)
+
+When any reward on the card is in pool mode and the card has a `child_id`, a banner above the rewards list shows the selected child's **Spendable** (what they can deposit right now) alongside their **gross balance**:
+
+```
+⭐ SPENDABLE 42 / 60 Points
+```
+
+## Examples
+
+### Basic single-child card
+
+```yaml
+type: custom:taskmate-rewards-card
+entity: sensor.taskmate_overview
+child_id: 8a3b2c1d4e5f6789
+```
+
+### Force everything on this card into Pool Mode
+
+```yaml
+type: custom:taskmate-rewards-card
+entity: sensor.taskmate_overview
+child_id: 8a3b2c1d4e5f6789
+enable_pool_mode: true
+title: "Alice's Savings Goals"
+```
+
+### Shared card showing rewards for all children (view-only)
+
+```yaml
+type: custom:taskmate-rewards-card
+entity: sensor.taskmate_overview
+title: "Family Rewards"
+```
+
+Without a `child_id`, the card shows a **child picker** and defaults to the first child, so claim and deposit buttons work immediately — tap a child's tab to switch who is claiming/depositing. Set `child_id` to pin the card to a single child (e.g. one card per child on a shared tablet).
+
+## Pool Mode details
+
+Pool Mode is controlled at two levels:
+
+- **Per reward** (**TaskMate** panel → **Rewards** → toggle "Pool Reward"). Rewards with the flag show deposit buttons; rewards without continue to show Claim.
+- **Per card** (`enable_pool_mode: true`). Forces every reward on this specific card into Pool Mode regardless of the per-reward flag.
+
+See [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) for the full guide.
+
+## Jackpot rewards
+
+Rewards with **Is Jackpot** enabled pool points across all assigned children. Jackpots are **always pool-mode** (there's no separate Pool toggle — the editor hides it): the card shows pooled **deposit** buttons and a segmented progress bar coloured per child, drawn from each child's allocation. The combined pool fills as children contribute, and any assigned child can **Redeem** once it reaches the cost — so a goal no single child could afford alone is reached together.
+
+## Per-period spending cap (v4.0.0)
+
+You can limit how many points each child is allowed to spend on rewards within a rolling period. The cap is a **global** setting (it applies to every child individually), configured in **Settings → History & streaks**, not per reward.
+
+| Setting | Default | Description |
+| --- | --- | --- |
+| **Spending cap** | `off` | Master toggle |
+| **Cap (pts)** | `0` | Maximum points spendable per period (`0` = no limit) |
+| **Period** | `weekly` | `weekly` (resets Monday) or `monthly` (resets on the 1st) |
+
+**How it works:**
+
+- Enforced at **approval** time. When a parent approves a reward claim, TaskMate adds up the cost of all of that child's already-approved claims in the current period.
+- If approving the new claim would push the total over the cap, the approval is **blocked** with a "Spending cap reached" error and no points are deducted. The claim stays pending — it can be approved in a later period or rejected.
+- Pending and rejected claims do not count toward the cap; only approved spend does.
+- The period boundary is the Monday of the current week (weekly) or the 1st of the current month (monthly).
+
+See [Managing Rewards](Managing-Rewards.md) for the admin workflow.
+
+## Auto-restock (v4.0.0)
+
+Limited-stock rewards can refill their quantity automatically on a schedule, so you don't have to top them up by hand. Restock is set **per reward** in the reward's add/edit dialog.
+
+| Field | Default | Description |
+| --- | --- | --- |
+| **Auto-restock** | `off` | Enable scheduled restocking for this reward |
+| **Restock to** | `0` | The quantity to reset stock back to each period |
+| **Restock every** | `Week (Mon)` | `Day`, `Week (Mon)`, or `Month (1st)` |
+
+**How it works:**
+
+- On the period boundary (daily = every day, weekly = Mondays, monthly = the 1st) the reward's **Quantity** is reset to the **Restock to** amount.
+- Restock overwrites the current quantity — it sets stock back to the amount rather than adding to it. A reward that sold out mid-period becomes available again.
+- A reward must have a restock amount above 0 and the toggle enabled, otherwise nothing happens.
+- A guard prevents restocking the same reward twice in one day.
+
+Restock only makes sense for rewards with a limited **Quantity**. See [Managing Rewards](Managing-Rewards.md) for setup.
+
+## Related
+
+- [Managing Rewards](Managing-Rewards.md) — create and edit rewards
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — the savings-jar feature
+- [Wishlist](Wishlist.md) — children save towards things they want, and the family can chip in
+- [Timed Unlock Rewards](Timed-Unlock-Rewards.md) — spend points to unlock a device for a while
+- [Time-Locked Rewards](Time-Locked-Rewards.md) — limit when a reward can be claimed
+- [Reject Reasons](Reject-Reasons.md) — the "Not approved: …" note a child sees when a claim is rejected
+- [Services](Services.md) — underlying services the card calls
diff --git a/wiki/Routine-Mode.md b/wiki/Routine-Mode.md
new file mode 100644
index 00000000..0d0cd3fc
--- /dev/null
+++ b/wiki/Routine-Mode.md
@@ -0,0 +1,77 @@
+# Routine Mode
+
+A guided, one-task-at-a-time flow for morning and bedtime routines.
+
+
+
+The standard child card is a checklist. That is good for scanning but poor for walking a five-year-old through getting ready — a list of eight things is a list of eight chances to get distracted. Routine mode shows a **single task at a time** with a big **Done** button, a progress bar, and a celebration at the end.
+
+---
+
+## Adding the Card
+
+```yaml
+type: custom:taskmate-routine-card
+entity: sensor.taskmate_overview
+child_id:
+time_category: morning # morning | afternoon | evening | night | anytime | all
+title: Vaiha's morning # optional
+card_design: global # optional — see Card Design Styles
+```
+
+| Control | Effect |
+|---------|--------|
+| **Done** | Completes the chore and moves to the next one. |
+| **Skip for now** | Moves on without completing — the task stays outstanding. |
+| **Back** | Returns to the previous task, so a mis-tap is recoverable. |
+
+---
+
+## Key Points
+
+- **Availability comes from the integration itself.** The card reads the same chore-availability matrix everything else uses, so the [weather gate](Weather-Aware-Chores.md), [reactive deadlines](Reactive-Chores.md), [dependencies](Chore-Dependencies.md), rotation and [vacation mode](Vacation-Mode.md) are all honoured automatically — and stay honoured as those features evolve.
+- Tasks appear in the child's **configured chore order**, the same order they have on the child card.
+- **`time_category` is exact.** A `morning` routine shows only morning chores — `anytime` chores are *not* mixed in, because a routine is a specific sequence rather than "everything currently doable". Use `all` if you want everything. This deliberately differs from the child card's convention.
+- Chores needing approval show **"waiting for a grown-up"**, and their points are totalled separately on the finish screen from points already banked.
+- **The finish screen totals what was earned in that run**, not the whole day.
+- An empty period shows a **"nothing to do"** state rather than an empty list.
+- Skipping a task and then completing it later correctly stops counting it as left for later.
+
+---
+
+## Choosing a Time Category
+
+Give a child two cards — one for each end of the day — and each shows only its own sequence:
+
+```yaml
+# Morning dashboard
+type: custom:taskmate-routine-card
+entity: sensor.taskmate_overview
+child_id:
+time_category: morning
+title: Morning
+
+# Bedtime dashboard
+type: custom:taskmate-routine-card
+entity: sensor.taskmate_overview
+child_id:
+time_category: night
+title: Bedtime
+```
+
+For this to work, set each chore's **time of day** in the chore editor. Chores left as `anytime` will only ever appear in an `all` routine.
+
+---
+
+## Design Styles
+
+The routine card supports all six [card design styles](Card-Design-Styles.md), set per card with `card_design` or from the global default. The **Accessible** style is worth considering here in particular: a guided one-task flow is often exactly what a child who needs high contrast and dyslexia-friendly type is using.
+
+---
+
+## Related
+
+- [Dashboard Cards](Dashboard-Cards.md) — every Lovelace card TaskMate ships
+- [Pre-Reader Mode](Pre-Reader-Mode.md) — a picture-only card for children who can't read yet
+- [Card Design Styles](Card-Design-Styles.md) — Classic, Playroom, Console, Clean Pro and Accessible
+- [Chores](Chores.md) — setting a chore's time of day and order
diff --git a/wiki/Scheduled-Config-Changes.md b/wiki/Scheduled-Config-Changes.md
new file mode 100644
index 00000000..5b2c21e5
--- /dev/null
+++ b/wiki/Scheduled-Config-Changes.md
@@ -0,0 +1,60 @@
+# Scheduled Config Changes
+
+Queue an edit to a chore that takes effect on a future date — *"from 1 September this chore is worth 20 points"*, *"from November it's disabled for the winter"*. Set it once, in the moment you thought of it, and forget it.
+
+
+
+Open a chore in the TaskMate panel and expand **Advanced — scheduled changes**. Pick a date, a field, and the new value. Queued changes are listed with a count badge on the section, and can be removed before they fire.
+
+---
+
+## What Can Be Scheduled
+
+Points · Assigned to · Enabled · Requires approval · Daily limit · Days · Mandatory · Penalty points · Expires on · Description · Time of day · Difficulty
+
+Runtime state — rotation anchors, skip dates, calendar publish history — deliberately **cannot** be scheduled. A queued change can only touch configuration, never the record of what actually happened.
+
+---
+
+## How It Works
+
+- Changes are applied during **midnight maintenance**.
+- **Missed days catch up.** If Home Assistant was switched off on the day a change was due, it is applied on the next start. A parent who wrote "from 1 September" still expects it to have happened, even if the server was down that night.
+- **Values are validated when you queue them**, not at midnight three weeks later. A bad value fails in front of you, while you still remember what you meant.
+- **The date must be in the future.** Today is rejected, because a change queued for today would actually fire at the *next* midnight — a day later than it reads.
+- **Applied changes are kept**, not deleted, and shown under **Already applied**. A configuration change that happens silently is worse than one that doesn't happen at all.
+- **Deleting a chore removes its queued changes.**
+
+---
+
+## Reacting to a Change
+
+Applying fires `taskmate_scheduled_change_applied`:
+
+| Field | Meaning |
+|-------|---------|
+| `change_id` | The queued change that fired |
+| `chore_id` | The chore it altered |
+| `chore_name` | Its name |
+| `changes` | The fields that were changed |
+| `timestamp` | When it was applied |
+
+---
+
+## Examples
+
+| Situation | Queue |
+|-----------|-------|
+| Term starts again | *From 1 September:* **Points → 20** |
+| Garden closes for winter | *From 1 November:* **Enabled → off** |
+| Child is old enough now | *From their birthday:* **Difficulty → hard** |
+| Sibling takes over the bins | *From 1 March:* **Assigned to → other child** |
+
+---
+
+## Related
+
+- [Chores](Chores.md) — the chore editor and every field a change can target
+- [Chore Scheduling](Chore-Scheduling.md) — recurring schedules, which are a different thing: *when a chore is due*, not *when its configuration changes*
+- [Automations](Automations.md) — every TaskMate bus event
+- [Admin Audit Log](Admin-Audit-Log.md) — the record of what changed and when
diff --git a/wiki/Sensor-Attributes.md b/wiki/Sensor-Attributes.md
new file mode 100644
index 00000000..db07aacb
--- /dev/null
+++ b/wiki/Sensor-Attributes.md
@@ -0,0 +1,255 @@
+# Sensor Attributes
+
+TaskMate exposes one primary overview sensor and a set of per-child sensors. Automations, templates, and custom cards can read from these.
+
+
+
+## `sensor.taskmate_overview`
+
+**State**: number of children.
+
+This is the main sensor. Its `extra_state_attributes` contain everything most cards and automations need.
+
+### Top-level attributes
+
+| Attribute | Type | Description |
+| --- | --- | --- |
+| `total_children` | int | Number of children |
+| `total_chores` | int | Number of defined chores |
+| `total_rewards` | int | Number of defined rewards |
+| `total_points_available` | int | Sum of all children's points |
+| `total_chores_completed` | int | Lifetime chore completions |
+| `total_completions_all_time` | int | Lifetime chore completion records |
+| `total_pending_completions` | int | Chore completions awaiting approval |
+| `today_day_of_week` | string | Lowercase day name, e.g. `"friday"` |
+| `points_name` | string | Customisable points currency name |
+| `points_icon` | string | MDI icon string |
+| `card_design` | string | (v4.1.0) Global default [card design style](Card-Design-Styles.md) — `classic` / `playroom` / `console` / `cleanpro` / `accessible` (default `classic`); cards apply it when they have no per-card override |
+| `children` | list | Per-child objects (see below) |
+| `chores` | list | Per-chore objects |
+| `rewards` | list | Per-reward objects (see below) |
+| `todays_completions` | list | Chore completions logged today |
+| `pending_reward_claims` | list | Reward claims awaiting approval |
+| `pool_allocations` | list | (v3.0+) Raw `PoolAllocation` records |
+| `time_boundaries` | dict | Legacy fixed time-window map (`morning_start`/`morning_end`/…) in `HH:MM` |
+| `time_periods` | list | (v4.0+) Custom time-of-day periods — each `id`, `label`, `start`, `end`, `icon`. See [Settings](Settings.md#custom-time-of-day-periods-v400) |
+| `vacation_active` / `vacation_name` / `vacation_end` | bool / string | (v4.0+) Active [vacation period](Vacation-Mode.md) state |
+| `vacation_periods` | list | (v4.0+) All configured vacation periods (`id`, `name`, `start`, `end`) |
+| `family_goal` | object | (v4.4.0) Shared co-op [family goal](Family-Goals.md) state (`enabled`, `name`, `target`, `progress`, `reward`, `achieved`) |
+| `season_month` | string | (v4.4.0) Current leaderboard season month, `YYYY-MM`. See [Leaderboard Seasons](Leaderboard-Seasons.md) |
+| `season_champions` | list | (v4.4.0) Past monthly leaderboard champions (newest first, up to 12) |
+| `companion_entities` | dict | (v6.1.0) Where each companion sensor really lives: role (`chores`, `rewards`, `activity`, `bounties`, `auctions`, `chore_board`, …) → entity ID. Cards use it to find sensors that Home Assistant created with an area prefix or that you renamed. Not recorded in history |
+| `badge_entities` | dict | (v6.1.0) Child ID → that child's badges sensor entity ID. Not recorded in history |
+| Settings mirrors | various | `streak_reset_mode`, `weekend_multiplier`, `streak_milestones_enabled`, `streak_milestones`, `perfect_week_enabled`, `perfect_week_bonus`, and (v6.0.0) `streak_freeze_max`, `streak_freeze_earn_every` |
+
+> **Note:** Heavy lists (`chores`, `rewards`, `todays_completions`, `recent_completions`, `recent_transactions`, `pending_reward_claims`, `pool_allocations`) have been moved to companion sensors (`sensor.taskmate_chores`, `sensor.taskmate_rewards`, `sensor.taskmate_activity`). Cards merge them transparently via the `__taskmate_attrs` helper. See [Sensor Reference](Sensor-Reference.md) for full details.
+
+### `children[]` entries
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `id` | string | Stable child ID |
+| `name` | string | Display name |
+| `avatar` | string | MDI icon (currently selected avatar) |
+| `avatar_image` | string | (v6.4.0) The child's [photo](Children.md#child-photos), from their **Photo from** entity. Empty when there is none; cards then show `avatar` |
+| `is_adult` | bool | (v6.4.0) `true` for an [adult profile](Adult-Profiles.md). Present only for adults |
+| `level` | int | (v4.0+) XP level derived from `total_points_earned`. See [Levels and XP](Levels-and-XP.md) |
+| `level_progress` | int | (v4.0+) XP into the current level band |
+| `level_target` | int | (v4.0+) XP per level (`level_xp_step`, default 100) |
+| `points` | int | Gross balance (after pool deposits have been subtracted) |
+| `pending_points` | int | Points earned from approved chores not yet applied |
+| `committed_points` | int | Points tied up in pending reward claims |
+| `spendable_balance` | int | (v3.0+) `points − committed_points` — what the child can spend or deposit now |
+| `allocated_points` | int | (v3.0+) Total points the child has deposited across all pools |
+| `total_points_earned` | int | Lifetime points earned |
+| `total_chores_completed` | int | Lifetime chores completed |
+| `current_streak` | int | Current consecutive-day streak |
+| `best_streak` | int | Highest streak achieved |
+| `season_points` | int | (v4.4.0) Points earned this leaderboard season (current month). See [Leaderboard Seasons](Leaderboard-Seasons.md) |
+| `week_points_earned` | int | (v6.4.0) Approved chore points since Monday (bonus sub-tasks excluded). Used by the [Sticker Chart](Sticker-Chart-Card.md)'s week goal |
+| `week_points_available` | int | (v6.4.0) The most this week's scheduled chores could pay, with the weekend multiplier and without vacation days. Rotation chores aren't counted, so `week_points_earned` can run past it |
+| `last_completion_date` | string \| null | ISO date of last completion |
+| `streak_paused` | bool | `true` if streak is currently paused |
+| `streak_milestones_achieved` | list[int] | Streak milestones unlocked |
+| `awarded_perfect_weeks` | list[string] | ISO Monday dates of perfect weeks |
+| `chore_order` | list[string] | Custom ordering of chore IDs |
+| `career_score` | int | Long-term performance metric (`total_points_earned − total_penalties_received`) |
+| `total_penalties_received` | int | Lifetime count of penalties applied |
+| `quests` | list | (v4.0+) Per-child [quest](Quests.md) progress (`quest_id`, `name`, `icon`, `total_steps`, `step`, `done`, `times_completed`, `bonus_points`, `next_chore_id`) |
+| `challenges` | list | (v4.0+) Per-child [challenge](Challenges.md) progress (`challenge_id`, `name`, `icon`, `scope`, `metric`, `target`, `progress`, `value`, `bonus_points`, `complete`, `awarded`) |
+| `avatar_options` | list | (v4.0+) [Avatar](Avatars.md) catalogue for this child (`id`, `label`, `icon`, `unlocked`, `requirement`) |
+| `birthday` | object | (v6.0.0) Only on the child's [birthday](Birthday-Mode.md): `multiplier`, `age` (when the year is known), `chores_off` |
+| `streak_freezes` | int | (v6.0.0) [Streak freeze](Streak-Freezes.md) tokens held. Only present while streak freezes are on |
+| `rejections` | list | (v6.0.0) Items sent back with a [reason](Reject-Reasons.md) in the last 24 hours (`kind`, `id`, `reason`, `at`). Only present when there is one |
+| `inspections` | list | (v6.0.0) Today's [inspection](Surprise-Inspections.md) banners (`id`, `chore_id`, `name`, `status`, plus `bonus` / `until` / `points` / `note` where relevant). Only present when there is one |
+| `help` | list | (v7.0.0) Chore IDs with an open [help request](Help-Requests.md). Present only when there is one |
+| `mood_today` | string | (v7.0.0) Today's [mood](Mood-Check-In.md) (`great` / `good` / `ok` / `sad` / `upset`), once the child has said |
+| `sick_today` | bool | (v7.0.0) `true` on a [sick day](Sick-Days.md). Present only then |
+| `pet` | object | (v7.0.0) The child's [virtual pet](Virtual-Pets.md) (`adopted`, `name`, `species`, `stage`, `mood`, `xp`, `accessories`, …). Present only while pets are on |
+| `weekly_goal` | object | (v7.0.0) The child's [weekly goal](Weekly-Goals.md) (`target`, `bonus`, `earned`, `reached`). Present only while weekly goals are on |
+| `redemptions` | list | (v7.0.0) Open [make-it-right](Make-It-Right-Penalties.md) offers (`id`, `chore_id`, `chore_name`, `penalty_name`, `points`, `expires`). Present only when there is one |
+
+> Full field-by-field tables for `quests`, `challenges`, and `avatar_options` are in the [Sensor Reference](Sensor-Reference.md#children-array).
+
+### `rewards[]` entries
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `id` | string | Stable reward ID |
+| `name` | string | Display name |
+| `description` | string | Optional description |
+| `icon` | string | MDI icon |
+| `cost` | int | Points cost |
+| `assigned_to` | list[string] | Child IDs the reward applies to (empty = all) |
+| `is_jackpot` | bool | Community goal — pools across all assigned children |
+| `pool_enabled` | bool | (v3.0+) When `true`, this reward uses savings-jar semantics |
+| `calculated_costs` | `{child_id: int}` | Per-child cost (currently static; all equal `cost`) |
+| `pool_allocations` | `{child_id: int}` | (v3.0+) Points each assigned child has deposited |
+| `jackpot_pool_total` | int \| null | (v3.0+) Combined pool for jackpot rewards; `null` otherwise |
+| `quantity` | int \| null | Remaining stock (`null` = unlimited) |
+| `expires_at` | string \| null | ISO date expiry deadline (`null` = never) |
+| `is_sold_out` | bool | `true` when quantity has reached 0 |
+| `is_expired` | bool | `true` when past the expiry date |
+| `is_available` | bool | `true` when not sold out and not expired |
+| `days_until_expiry` | int \| null | Days remaining until expiry (`null` if no expiry set) |
+| `streak_freeze` | bool | (v6.0.0) `true` on a **Streak freeze** reward. Only present when set |
+
+### `chores[]` entries
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `id` | string | Stable chore ID |
+| `name`, `description` | string | Display |
+| `points` | int | Base points awarded on approval |
+| `difficulty` | string | (v4.0+) `easy`/`medium`/`hard` — only present when not `medium`. See [Difficulty Tiers](Difficulty-Tiers.md) |
+| `effective_points` | int | (v4.0+) Points after the difficulty multiplier — present only when it differs from `points` |
+| `mandatory` | bool | (v4.2.0) `true` for a [mandatory chore](Mandatory-Chores.md) — only present when set |
+| `mandatory_penalty_points` | int | (v4.2.0) Penalty deducted if missed — only present when `mandatory` is set and the penalty is non-zero. See [Mandatory Chores](Mandatory-Chores.md) |
+| `assigned_to` | list[string] | Child IDs (empty = all) |
+| `time_category` | string | `morning` / `afternoon` / `evening` / `night` / `anytime` |
+| `daily_limit` | int | Max completions per child per day |
+| `completion_sound` | string | Sound identifier |
+| `schedule_mode` | string | `specific_days`, `recurring`, or `one_shot` |
+| `assignment_mode` | string | `everyone` / `alternating` / `random` / `balanced` / `first_come` / `unassigned` |
+| `due_days` | list[string] | Used in `specific_days` mode |
+| `recurrence` / `recurrence_day` / `recurrence_start` | — | Used in `recurring` mode |
+| `first_occurrence_mode` | string | `available_immediately` / `wait_for_first_occurrence` |
+| `visibility_entity` / `visibility_state` / `visibility_operator` | — | Optional dynamic visibility guard |
+| `enabled` | bool | False = soft-disabled (one-shot completed or expired) |
+| `disabled_for` | list[string] | Child IDs this chore is disabled for |
+| `created_date` | string | ISO date for one-shot chore expiry |
+| `last_completed_at` | `{child_id: iso}` | Most recent completion per child |
+| `is_available` | `{child_id: bool}` | Whether chore shows for each child today |
+| `task_type` | string | `standard` or `timed` |
+| `timed_rate_points` | int | Points per rate window (timed chores) |
+| `timed_rate_minutes` | int | Rate window in minutes (timed chores) |
+| `timed_max_daily_minutes` | int | Daily cap in minutes; 0 = unlimited (timed chores) |
+| `bonus_subtasks` | list[dict] | Embedded subtasks — each has `id`, `name`, `points`, `description` |
+| `require_availability` | bool | Skip unavailable children in rotation |
+| `manual_start_child_id` | string | Forced rotation start child ID (if set) |
+| `publish_calendar_entities` | list[string] | HA calendar entity IDs for publishing |
+| `team` | object | (v6.0.0) [Teamwork chores](Teamwork-Chores.md) only: `size`, `joined` (child IDs), `split` |
+| `occ_today` | bool | (v6.0.0) Overrides whether the chore is due today — after a [calendar](Two-Way-Calendar.md) move or skip, or for a one-off dated another day |
+| `moved_occurrences` | `{iso: iso}` | (v6.0.0) Calendar moves, original date → new date (empty = skipped) |
+| `auction_wins` / `auction_prices` / `auction` | dict / dict / object | (v6.0.0) [Auction](Chore-Auctions.md) results this week: winner and price per day, and today's `{child_id, points}` |
+| `estimated_minutes` | int | (v7.0.0) [Estimated minutes](Estimated-Minutes.md). Only present when set |
+| `quantity_unit` / `quantity_max` / `unit_points` | string / int / float | (v7.0.0) [Quantity chores](Quantity-Chores.md): the unit, the per-completion cap (when set) and the unrounded per-unit worth (when it differs from `effective_points`) |
+
+### `pending_reward_claims[]` entries
+
+| Field | Type | Description |
+| --- | --- | --- |
+| `claim_id` | string | Claim ID |
+| `reward_id` | string | Reward ID |
+| `child_id` | string | Child ID |
+| `child_name` | string | Display name |
+| `child_avatar` | string | MDI icon |
+| `reward_name` | string | Display name |
+| `reward_icon` | string | MDI icon |
+| `cost` | int | Points cost |
+| `claimed_at` | string | ISO datetime |
+
+## `sensor.taskmate_pending_approvals`
+
+**State**: total pending (chores + claims).
+
+Attributes include `pending_chore_completions`, `pending_reward_claims`, `pending_mandatory_misses` (count), `chore_completions` (enriched list; a finished [bounty](Bounty-Board.md) carries `bounty_id`), `reward_claims` (enriched list; a [wish](Wishlist.md) being redeemed appears here like a reward), `quality_rating` (v6.0.0, present only while [quality ratings](Quality-Ratings.md) are on — `multipliers` for ★, ★★, ★★★), (v7.0.0) `quantity` / `quantity_unit` and a signed `reference_image_url` on chore completions where the chore has them ([Quantity Chores](Quantity-Chores.md), [Reference Photos](Reference-Photos.md)), and `mandatory_misses` (enriched list of [mandatory-miss](Mandatory-Chores.md) review items — each has `id`, `chore_id`, `child_id`, `chore_name`, `child_name`, `due_date`, `period_id`, `penalty_points`, `postpone_count`, `created_at`). See [Sensor Reference](Sensor-Reference.md#sensortaskmate_pending_approvals) and [Mandatory Chores](Mandatory-Chores.md).
+
+## Per-child sensors
+
+Each child gets two sensors created at onboarding:
+
+- **`sensor.taskmate__points`** — state is current gross balance; attributes include `child_id`, `child_name`, `avatar`, `avatar_image` (v6.4.0), `total_points_earned`, `total_chores_completed`, `current_streak`, `best_streak`
+- **`sensor.taskmate__stats`** — state is total chores completed; attributes include `child_id`, `child_name`, `avatar`, `avatar_image` (v6.4.0), `points`, `total_points_earned`, `total_chores_completed`, `current_streak`, `best_streak`, `assigned_chores` (list of today's assigned chores), `chore_order`. From v6.4.0 the stats sensor's entity picture is the child's [photo](Children.md#child-photos) when they have one
+
+(v6.0.0) Two more per child:
+
+- **`sensor.taskmate__wishlist`** — state is the number of wishes on the go; attributes `wishlist_child_id`, `wish_max_open` and `wishes` (each `id`, `name`, `target`, `status`, and when set `saved`, `pledged`, `pledges`, `link`, `image_url`, `decline_reason`). See [Wishlist](Wishlist.md)
+- **`sensor.taskmate__watch`** — state is a short phrase such as `3 left`, `All done` or `No chores`, in Home Assistant's language; attributes `child_id`, `status` (`to_do` / `all_done` / `no_chores`), `left`, `done`, `total`, `progress` (0–1), `points`, `streak`, `next_chore`. See [Watch Complications](Watch-Complications.md)
+
+## Companion sensors
+
+The overview sensor's heavy data has been split across companion sensors to stay under the 16KB recorder limit:
+
+| Sensor | State | Key attributes |
+|--------|-------|----------------|
+| `sensor.taskmate_chores` | Chore count | `chores`, `todays_completions` |
+| `sensor.taskmate_chore_availability` | Available chore/child pairs | `chore_availability` (matrix `{chore_id: {child_id: bool}}`) |
+| `sensor.taskmate_rewards` | Reward count | `rewards`, `pending_reward_claims`, `pool_allocations`, (v7.0.0) `raffles` — open [raffles](Raffles.md) and those finished in the last day. Not recorded in history |
+| `sensor.taskmate_activity` | All-time completion count | `recent_completions` (max 35), `recent_transactions` (max 20), `career_score_history`, `photo_gallery` (v4.4.0, max 40) |
+| `sensor.taskmate_incentives` | Penalty + bonus count | `penalties`, `bonuses`, `task_groups` |
+| `sensor.taskmate_bounties` | Open bounty count | (v6.0.0) `bounties` — the [bounty board](Bounty-Board.md): live bounties plus the last 24 hours' completed ones |
+| `sensor.taskmate_auctions` | Open auction count | (v6.0.0) `auctions` — open and recently closed [auctions](Chore-Auctions.md): bid counts and results only, never bid amounts |
+| `sensor.taskmate_chore_board` | Chores still to do today | (v6.1.0) `chore_board` — today's board for every child, as shown on the panel's Today page and the [Chore Board card](Dashboard-Cards.md#chore-board-card). Not recorded in history |
+
+See [Sensor Reference](Sensor-Reference.md) for full attribute details.
+
+## Attributes and the recorder *(v5.3.0+)*
+
+The large list attributes above — `chores`, `recent_completions`,
+`mandatory_misses`, `children`, the badge `earned` / `available` lists and so
+on — are declared **unrecorded**.
+
+They are still published on the live state, so **cards, `state_attr()`,
+templates and automation conditions read them exactly as before**. Only Home
+Assistant's recorder skips them, which keeps the database small and prevents
+this warning:
+
+```
+WARNING (Recorder) State attributes for sensor.taskmate_activity exceed
+maximum size of 16384 bytes. This can cause database performance issues;
+Attributes will not be stored
+```
+
+Scalar attributes (counts, totals, settings) stay recorded, so history and
+statistics on them keep working. The practical difference is that you cannot
+look up a *past* value of one of the big lists in history — the current value is
+always available on the state.
+
+## Calendar entities
+
+(v4.2.0) One calendar entity per child — **`calendar.taskmate_`** (friendly name `TaskMate `). It projects the child's upcoming chore occurrences and shows [away periods](Vacation-Mode.md) as all-day "Away" events; the state is the next upcoming event. Since v6.0.0 parents and admins can add, move and skip chores in it — see [Two-Way Calendar](Two-Way-Calendar.md). See [Calendar](Calendar.md) and [Sensor Reference](Sensor-Reference.md#calendar-entities-v420).
+
+## To-do and configuration entities
+
+(v4.4.0) TaskMate also creates:
+
+- **`todo.taskmate_`** — one to-do list per child of the chores they still need to do today; checking an item off completes that chore.
+- **`number.taskmate_weekend_multiplier`**, **`number.taskmate_perfect_week_bonus`**, **`select.taskmate_streak_reset_mode`**, **`select.taskmate_card_design`** — key settings surfaced as entities, in sync with the admin panel.
+
+See [Sensor Reference](Sensor-Reference.md#configuration-entities-v440) and [Configuration Entities](Configuration-Entities.md).
+
+## Event entities
+
+(v7.0.0) One **`event.taskmate__activity`** entity per child, plus **`event.taskmate_family_activity`**. They re-publish TaskMate's bus events, with the event's data as attributes, so they can be picked in the UI automation editor. See [Event Entities](Event-Entities.md) and [Sensor Reference](Sensor-Reference.md#event-entities-v700).
+
+## Related
+
+- [Services](Services.md) — services that modify these attributes
+- [Sensor Reference](Sensor-Reference.md) — full entity + attribute catalogue, including companion sensors and admin-panel-only data
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — context for the v3.0 pool attributes
+- [Levels and XP](Levels-and-XP.md), [Quests](Quests.md), [Challenges](Challenges.md), [Avatars](Avatars.md), [Vacation Mode](Vacation-Mode.md) — v4.0.0 features that surface in these attributes
+- [Mandatory Chores](Mandatory-Chores.md), [Card Design Styles](Card-Design-Styles.md), [Calendar](Calendar.md) — v4.1.0–v4.2.0 features that surface in these attributes
+- [Family Goals](Family-Goals.md), [Leaderboard Seasons](Leaderboard-Seasons.md), [Allowance](Allowance.md), [Photo Proof](Photo-Proof.md), [Configuration Entities](Configuration-Entities.md) — v4.4.0 features that surface in these attributes
+- [Birthday Mode](Birthday-Mode.md), [Streak Freezes](Streak-Freezes.md), [Reject Reasons](Reject-Reasons.md), [Surprise Inspections](Surprise-Inspections.md), [Teamwork Chores](Teamwork-Chores.md), [Chore Auctions](Chore-Auctions.md), [Bounty Board](Bounty-Board.md), [Wishlist](Wishlist.md), [Watch Complications](Watch-Complications.md) — v6.0.0 features that surface in these attributes
+- [Help Requests](Help-Requests.md), [Mood Check-In](Mood-Check-In.md), [Sick Days](Sick-Days.md), [Virtual Pets](Virtual-Pets.md), [Weekly Goals](Weekly-Goals.md), [Make-It-Right Penalties](Make-It-Right-Penalties.md), [Raffles](Raffles.md), [Estimated Minutes](Estimated-Minutes.md), [Quantity Chores](Quantity-Chores.md), [Reference Photos](Reference-Photos.md), [Event Entities](Event-Entities.md) — v7.0.0 features that surface in these attributes
diff --git a/wiki/Sensor-Reference.md b/wiki/Sensor-Reference.md
new file mode 100644
index 00000000..68c10e2b
--- /dev/null
+++ b/wiki/Sensor-Reference.md
@@ -0,0 +1,751 @@
+# Sensor Reference
+
+TaskMate creates the following entities in Home Assistant.
+
+
+
+> **Architecture note:** The overview sensor's attributes have been split across companion sensors (`sensor.taskmate_chores`, `sensor.taskmate_rewards`, etc.) to stay under the 16KB recorder limit. Cards use the `__taskmate_attrs` helper to transparently merge data from all sensors.
+
+---
+
+## sensor.taskmate_overview
+
+The main overview sensor. Carries scalar stats and the compact per-child summary.
+
+| Property | Value |
+|----------|-------|
+| State | Number of children |
+| Icon | `mdi:clipboard-check-multiple` |
+
+### Top-Level Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `total_children` | int | Number of children |
+| `total_chores` | int | Number of defined chores |
+| `total_rewards` | int | Number of defined rewards |
+| `total_points_available` | int | Sum of all children's current points |
+| `total_chores_completed` | int | Sum of all-time chore completions across all children |
+| `total_completions_all_time` | int | Lifetime chore completion records |
+| `total_pending_completions` | int | Chore completions awaiting approval |
+| `points_name` | string | Currency name (e.g. "Stars") |
+| `points_icon` | string | Currency MDI icon (e.g. "mdi:star") |
+| `card_design` | string | Global default [card design style](Card-Design-Styles.md) — `classic` / `playroom` / `console` / `cleanpro` / `accessible` (default `classic`). Cards apply this when they have no per-card override. See [Card Design Styles](Card-Design-Styles.md) |
+| `today_day_of_week` | string | Current day in HA timezone (e.g. "monday") |
+| `weekend_multiplier` | float | Current weekend multiplier setting |
+| `streak_reset_mode` | string | "reset" or "pause" |
+| `streak_milestones_enabled` | bool | Whether streak milestone bonuses are on |
+| `streak_milestones` | string | Current milestone configuration string |
+| `perfect_week_enabled` | bool | Whether perfect week bonus is on |
+| `perfect_week_bonus` | int | Perfect week bonus points value |
+| `streak_freeze_max` | int | (v6.0.0) Most [streak freeze](Streak-Freezes.md) tokens a child can hold; `0` = streak freezes off |
+| `streak_freeze_earn_every` | int | (v6.0.0) Streak days per free token; `0` = never earned automatically |
+| `time_boundaries` | dict | Legacy fixed time-window map: `morning_start`/`morning_end`/`afternoon_start`/… in `HH:MM` (kept for cards that read the four fixed periods) |
+| `time_periods` | list | Custom [time-of-day periods](Settings.md#custom-time-of-day-periods-v400) — each entry has `id`, `label`, `start`, `end`, `icon`. Drives chore time-category windows |
+| `vacation_active` | bool | `true` if a [vacation period](Vacation-Mode.md) covers today |
+| `vacation_name` | string | Name of the active vacation period (empty when none) |
+| `vacation_end` | string | ISO end date of the active vacation period (empty when none) |
+| `vacation_periods` | list | All configured vacation periods — each has `id`, `name`, `start`, `end`. See [Vacation Mode](Vacation-Mode.md) |
+| `family_goal` | object | (v4.4.0) Shared co-op [family goal](Family-Goals.md) state — `enabled` (bool), `name` (string), `target` (int), `reward` (string), `progress` (int — combined current points), `achieved` (bool). See [Family Goals](Family-Goals.md) |
+| `season_month` | string | (v4.4.0) Current leaderboard season month, `YYYY-MM` |
+| `season_champions` | list | (v4.4.0) Past monthly leaderboard champions (newest first, up to 12). See [Leaderboard Seasons](Leaderboard-Seasons.md) |
+
+> **Note:** Level/XP, quest, challenge, and avatar-unlock data are carried **per child** inside the `children` array (see below), not as top-level attributes. See [Levels and XP](Levels-and-XP.md), [Quests](Quests.md), [Challenges](Challenges.md), [Avatars](Avatars.md).
+
+### `children` Array
+
+Each entry in the `children` array:
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `id` | string | Child's unique ID |
+| `name` | string | Child's display name |
+| `avatar` | string | MDI icon (the child's currently selected avatar) |
+| `avatar_image` | string | (v6.4.0) The child's [photo](Children.md#child-photos), read from their **Photo from** entity. Empty when there is none; cards then show `avatar` |
+| `level` | int | Current XP level (derived from `total_points_earned`). See [Levels and XP](Levels-and-XP.md) |
+| `level_progress` | int | XP earned toward the next level within the current level band |
+| `level_target` | int | XP required per level (the `level_xp_step` setting; default 100) |
+| `points` | int | Current gross points balance (after pool deposits deducted) |
+| `pending_points` | int | Points held by pending chore approvals |
+| `committed_points` | int | Points reserved by pending reward claims |
+| `spendable_balance` | int | `points − committed_points` — what the child can spend or deposit now |
+| `allocated_points` | int | Total points deposited across all reward pools |
+| `total_points_earned` | int | All-time points earned |
+| `total_chores_completed` | int | All-time completions |
+| `current_streak` | int | Current consecutive day streak |
+| `best_streak` | int | Best streak ever |
+| `season_points` | int | (v4.4.0) Points earned this leaderboard season (current month). See [Leaderboard Seasons](Leaderboard-Seasons.md) |
+| `week_points_earned` | int | (v6.4.0) Approved chore points since Monday, bonus sub-tasks excluded |
+| `week_points_available` | int | (v6.4.0) The most this week's scheduled chores could pay: every scheduled chore at its daily limit across Monday–Sunday, with the weekend and birthday multipliers, without vacation days; a weekly-target chore adds its target × points once. Rotation chores aren't counted, so `week_points_earned` can run past it. Read by the [Sticker Chart](Sticker-Chart-Card.md)'s week goal |
+| `chore_order` | list | Custom chore display order |
+| `last_completion_date` | string | ISO date of last completion |
+| `streak_paused` | bool | Whether streak is paused |
+| `streak_milestones_achieved` | list | Milestone day counts already awarded this streak |
+| `awarded_perfect_weeks` | list | Monday ISO dates of awarded perfect weeks |
+| `career_score` | int | Long-term score (`total_points_earned − total_penalties_received`) |
+| `total_penalties_received` | int | Lifetime count of penalties applied |
+| `quests` | list | This child's [quest](Quests.md) progress — each entry has `quest_id`, `name`, `icon`, `total_steps`, `step`, `done`, `times_completed`, `bonus_points`, `next_chore_id` |
+| `challenges` | list | This child's [challenge](Challenges.md) progress — each entry has `challenge_id`, `name`, `icon`, `scope`, `metric`, `target`, `progress`, `value`, `bonus_points`, `complete`, `awarded` |
+| `avatar_options` | list | The [avatar catalogue](Avatars.md) resolved for this child — each entry has `id`, `label`, `icon`, `unlocked`, `requirement` (human-readable unlock condition) |
+| `is_guest` | bool | (v5.0.0) Present only for [guest profiles](Guest-Child-Profiles.md) |
+| `guest_expires_on` | string | (v5.0.0) ISO date the guest profile is archived; present only for guests |
+| `is_adult` | bool | (v6.4.0) `true` for an [adult profile](Adult-Profiles.md); present only for adults |
+| `roulette` | object | (v5.0.0) Today's [roulette](Chore-Roulette.md) pick and `spins_left`; present only while roulette is enabled |
+| `birthday` | object | (v6.0.0) Present only on the child's [birthday](Birthday-Mode.md): `multiplier` (float), `age` (int, when the birth year is known) and `chores_off: true` when the birthday day off is on |
+| `streak_freezes` | int | (v6.0.0) [Streak freeze](Streak-Freezes.md) tokens the child holds. Present only while streak freezes are switched on, so `0` means "none left" rather than "not in use" |
+| `rejections` | list | (v6.0.0) Recently sent-back chores and reward claims with a [reason](Reject-Reasons.md), newest first — each has `kind` (`chore` / `reward`), `id` (the chore or reward ID), `reason` and `at` (ISO datetime). Kept for 24 hours, or until the child tries again. Present only when there is one |
+| `inspections` | list | (v6.0.0) Today's [inspection](Surprise-Inspections.md) banners for the child card (up to 4) — each has `id`, `chore_id`, `name`, `status` (`open` / `passed` / `failed` / `redo`), plus `bonus` and `until` while open, `bonus` when passed, `points` for a redo, and an optional `note`. A secret inspection is not listed until it is decided. Present only when there is one |
+| `help` | list | (v7.0.0) Chore IDs the child has an open [help request](Help-Requests.md) for ("I'm stuck"), newest first. A request stays open until a parent answers it, or for two hours. Present only when there is one |
+| `mood_today` | string | (v7.0.0) Today's [mood check-in](Mood-Check-In.md): `great`, `good`, `ok`, `sad` or `upset`. Present only once the child has said |
+| `sick_today` | bool | (v7.0.0) `true` on a [sick day](Sick-Days.md). Present only then |
+| `pet` | object | (v7.0.0) The child's [virtual pet](Virtual-Pets.md), present only while pets are switched on. `{adopted: false}` before adoption; afterwards `adopted`, `name`, `species`, `stage` (`egg` / `baby` / `kid` / `teen` / `grown`), `chores` (since adoption), `xp` (growth), `mood` (`happy` / `proud` / `content` / `sleepy`), `accessories`, plus, when reached or switched on, `goal`, `legendary`, `home`, `pet_level`, `egg_ready` and `family` (earlier pets: `species`, `name`, `legendary`) |
+| `weekly_goal` | object | (v7.0.0) The child's own [weekly goal](Weekly-Goals.md), present only while weekly goals are switched on: `target` (0 = not set), `bonus`, and once a target is set `earned` (points since Monday) and `reached` |
+| `redemptions` | list | (v7.0.0) Open [make-it-right](Make-It-Right-Penalties.md) offers — each has `id`, `chore_id`, `chore_name`, `penalty_name`, `points` (what doing the chore gives back) and `expires` (ISO date, the last day it can be done). Present only when there is one |
+
+**`quests` entry fields:**
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `quest_id` | string | Quest ID |
+| `name` | string | Quest display name |
+| `icon` | string | MDI icon |
+| `total_steps` | int | Number of chore steps in the chain |
+| `step` | int | Child's current step (0-indexed, capped at `total_steps`) |
+| `done` | bool | `true` when `step >= total_steps` |
+| `times_completed` | int | How many times this child has completed the chain |
+| `bonus_points` | int | Points awarded on completing the final step |
+| `next_chore_id` | string | Chore ID of the next step to complete (empty when done) |
+
+**`challenges` entry fields:**
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `challenge_id` | string | Challenge ID |
+| `name` | string | Challenge display name |
+| `icon` | string | MDI icon |
+| `scope` | string | `daily` or `weekly` (week starts Monday) |
+| `metric` | string | `chores` (count of completions) or `points` (points earned) |
+| `target` | int | Goal value for the metric this period |
+| `progress` | int | Progress toward target, capped at `target` |
+| `value` | int | Actual current value (may exceed `target`) |
+| `bonus_points` | int | Points awarded once the target is hit |
+| `complete` | bool | `true` when `value >= target` |
+| `awarded` | bool | `true` when the bonus has already been credited this period |
+
+**`avatar_options` entry fields:**
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `id` | string | Avatar catalogue ID |
+| `label` | string | Display name |
+| `icon` | string | MDI icon |
+| `unlocked` | bool | Whether this child meets the unlock condition |
+| `requirement` | string | Human-readable unlock condition — `""` (free), `"Level X"`, `"X earned"`, or `"X-day streak"` |
+
+> **Note:** The following arrays (`chores`, `rewards`, `todays_completions`, `recent_completions`, `recent_transactions`, `pending_completions`, `pending_reward_claims`) are served by companion sensors (see below). Cards merge them transparently via the `__taskmate_attrs` helper.
+
+### `chores` Array
+
+Each entry in the `chores` array (from `sensor.taskmate_chores`):
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `id` | string | Chore's unique ID |
+| `name` | string | Display name |
+| `description` | string | Optional description (omitted when empty) |
+| `points` | int | Base points (before multipliers) awarded on completion |
+| `difficulty` | string | `easy` / `medium` / `hard` — only emitted when **not** `medium`. See [Difficulty Tiers](Difficulty-Tiers.md) |
+| `effective_points` | int | Points actually awarded after the difficulty multiplier — only emitted when it differs from `points` |
+| `mandatory` | bool | `true` for a [mandatory chore](Mandatory-Chores.md) — only emitted when set (so cards can show the mandatory badge/styling) |
+| `mandatory_penalty_points` | int | Penalty deducted if the chore is missed — only emitted when `mandatory` is set **and** the penalty is non-zero. See [Mandatory Chores](Mandatory-Chores.md) |
+| `require_photo` | bool | `true` when the chore requires a [photo proof](Photo-Proof.md) — only emitted when set |
+| `time_category` | string | morning / afternoon / evening / night / anytime |
+| `schedule_mode` | string | `specific_days` / `recurring` / `one_shot` |
+| `daily_limit` | int | Max completions per day (omitted when 1) |
+| `weekly_target` | int | Completions needed per week, see [Weekly Targets](Weekly-Targets.md) (omitted when 0) |
+| `weekly_target_bonus` | int | (v6.2.0) Bonus paid when the weekly target is reached. Only emitted when `weekly_target` is set and the bonus is non-zero |
+| `claim_allowance_minutes` | int | Grace minutes past the period end during which the chore stays claimable (omitted when 0) |
+| `assigned_to` | list | List of child IDs (empty = all children) |
+| `completion_sound` | string | Sound name (omitted when default `coin`) |
+| `due_days` | list | Scheduled days for `specific_days` mode (omitted when empty) |
+| `recurrence` | string | `every_2_days` / `weekly` / `every_2_weeks` / `monthly` / `every_3_months` / `every_6_months`, or `every__days` (N = 2–365, v6.2.0) for a custom [Every N days](Chore-Scheduling.md#every-n-days-custom) chore (omitted when `weekly`) |
+| `recurrence_day` | string | Day-of-week anchor for recurring weekly/fortnightly (omitted when empty) |
+| `recurrence_start` | string | ISO date anchor for `every_2_days` / `every__days` recurrence (omitted when empty) |
+| `visibility_entity` / `visibility_operator` / `visibility_state` | string | Dynamic visibility guard — emitted together when `visibility_entity` is set. See [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) |
+| `requires_approval` | bool | Whether parent approval is needed (omitted when `true` — default) |
+| `assignment_mode` | string | `everyone` / `alternating` / `random` / `balanced` / `first_come` / `unassigned`. See [Chore Scheduling](Chore-Scheduling.md) |
+| `assignment_current_child_id` | string | Child ID assigned today (for alternating/random/balanced modes; omitted when empty) |
+| `enabled` | bool | Whether the chore is active (`false` for soft-disabled one-shot chores) |
+| `disabled_for` | list | Child IDs for whom this chore is individually disabled |
+| `created_date` | string | ISO date for one-shot chore expiry (e.g. `"2026-04-16"`) |
+| `task_type` | string | `standard` or `timed` |
+| `timed_rate_points` | int | Points per rate window (timed chores only) |
+| `timed_rate_minutes` | int | Rate window in minutes (timed chores only) |
+| `timed_max_daily_minutes` | int | Daily cap in minutes; 0 = unlimited (timed chores only) |
+| `bonus_subtasks` | list | Embedded bonus subtasks — each has `id`, `name`, `points` (description is omitted from the sensor payload) |
+| `team` | object | (v6.0.0) Only on a [teamwork chore](Teamwork-Chores.md): `size` (children needed), `joined` (child IDs who have joined today; omitted when none) and `split: true` when the points are divided. On a teamwork chore `effective_points` is each member's share |
+| `occ_today` | bool | (v6.0.0) Present only when today's occurrence has been moved or removed from the [calendar](Two-Way-Calendar.md), or on a one-off chore dated for another day. `false` means the chore is not due today even if its schedule says so; `true` means an occurrence was moved onto today |
+| `moved_occurrences` | dict | (v6.0.0) Occurrences moved in the calendar, `{original ISO date: new ISO date}` (an empty target means the day was skipped). Only moves from the last 7 days onward |
+| `auction_wins` | dict | (v6.0.0) Days this week won at [auction](Chore-Auctions.md), `{ISO date: child_id}` |
+| `auction_prices` | dict | (v6.0.0) What each won day pays, `{ISO date: points}` |
+| `auction` | object | (v6.0.0) Today's auction result, `{child_id, points}`. Only the winner does the chore today, and `effective_points` is the winning price |
+| `estimated_minutes` | int | (v7.0.0) Roughly how long the chore takes, in minutes. See [Estimated Minutes](Estimated-Minutes.md). Only emitted when set |
+| `quantity_unit` | string | (v7.0.0) The unit of a [quantity chore](Quantity-Chores.md) ("pages"); `points` is then per unit. Only emitted when set (and never on open-ended or timed chores) |
+| `quantity_max` | int | (v7.0.0) Most units one completion counts. Only emitted when the chore has a cap |
+| `unit_points` | float | (v7.0.0) Per-unit worth after the difficulty multiplier, unrounded. Only emitted on a quantity chore when it differs from `effective_points` |
+
+> **Compact payloads:** The chores sensor deliberately omits rarely-used fields to stay under the 16KB recorder limit. `publish_calendar_entities`, `last_completed_at`, `first_occurrence_mode`, `assignment_rotation_anchor`, and the per-child availability matrix are **not** in this list. Per-child availability lives on [`sensor.taskmate_chore_availability`](#sensortaskmate_chore_availability). The chore editor fields `expires_on`, `due_time` / `early_bonus` / `late_penalty`, and `require_availability` are stored on the chore but are not emitted on this sensor; manage them in the [Admin Panel](Admin-Panel.md).
+
+
+### `rewards` Array
+
+Each entry in the `rewards` array:
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `id` | string | Reward's unique ID |
+| `name` | string | Display name |
+| `description` | string | Optional description |
+| `cost` | int | Fixed point cost set by the parent |
+| `icon` | string | MDI icon |
+| `assigned_to` | list | Child IDs (empty = all children) |
+| `is_jackpot` | bool | Whether this is a pooled jackpot reward |
+| `pool_enabled` | bool | Whether this reward uses savings-jar (pool) semantics |
+| `calculated_costs` | dict | Per-child cost `{child_id: cost}` |
+| `pool_allocations` | dict | Per-child pool deposits `{child_id: points}` |
+| `jackpot_pool_total` | int\|null | Combined pool total for jackpot rewards; `null` otherwise |
+| `quantity` | int\|null | Remaining stock (null = unlimited) |
+| `expires_at` | string\|null | ISO date expiry deadline (null = never) |
+| `is_sold_out` | bool | `true` when quantity has reached 0 |
+| `is_expired` | bool | `true` when past the expiry date |
+| `is_available` | bool | `true` when not sold out and not expired |
+| `days_until_expiry` | int\|null | Days remaining until expiry (null if no expiry set) |
+| `streak_freeze` | bool | (v6.0.0) `true` on a **Streak freeze** reward, which gives the child one [streak freeze](Streak-Freezes.md) token when approved. Only present when set |
+
+> **Note:** Auto-restock fields (`restock_enabled`, `restock_amount`, `restock_period`, `restock_last`) are stored on the reward but are **not** emitted on the sensor — they drive the periodic stock reset only. The reward-level [spending cap](Points-Economy.md) is a global setting, not a per-reward field. See [Points Economy](Points-Economy.md) and [Rewards](Rewards.md).
+
+### `todays_completions` Array
+
+Completions from today (both approved and pending):
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `completion_id` | string | Unique completion ID |
+| `chore_id` | string | Chore ID |
+| `child_id` | string | Child ID |
+| `child_name` | string | Child display name |
+| `chore_name` | string | Chore display name |
+| `points` | int | Points value |
+| `approved` | bool | Whether approved |
+| `completed_at` | string | ISO datetime |
+| `child_undo_pending` | bool | (v6.0.0) `true` when the child may still withdraw this pending submission. Only present while the [child undo window](Child-Undo-Window.md) is on |
+| `child_undo_until` | string | (v6.0.0) ISO datetime until which the child may undo this automatically approved chore. Only present while it can still be undone |
+| `quantity` | int | (v7.0.0) How many units the child did on a [quantity chore](Quantity-Chores.md). Only present on those |
+
+A chore that a [surprise inspection](Surprise-Inspections.md) sent back to redo is left out, because it is owed again today.
+
+### `recent_completions` Array
+
+Up to 35 most recent completions across all time (capped to stay under the 16KB recorder limit).
+
+Same fields as `todays_completions`, plus `rating` (v6.0.0, 1–3) when the parent gave a [quality rating](Quality-Ratings.md) at approval. A finished [bounty](Bounty-Board.md) appears here with the bounty's title as `chore_name`.
+
+### `pending_completions` Array
+
+Unapproved chore completions waiting for parent action:
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `completion_id` | string | Unique completion ID |
+| `chore_id` | string | Chore ID |
+| `child_id` | string | Child ID |
+| `child_name` | string | Child display name |
+| `chore_name` | string | Chore display name |
+| `points` | int | Points value |
+| `time_category` | string | Time of day |
+| `completed_at` | string | ISO datetime |
+
+### `pending_reward_claims` Array
+
+Unapproved reward claims waiting for parent action:
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `claim_id` | string | Unique claim ID |
+| `reward_id` | string | Reward ID |
+| `child_id` | string | Child ID |
+| `child_name` | string | Child display name |
+| `reward_name` | string | Reward display name |
+| `cost` | int | Points cost at time of claim |
+| `claimed_at` | string | ISO datetime |
+
+### `recent_transactions` Array
+
+Up to 20 most recent points transactions and reward claim events:
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `id` | string | Transaction ID |
+| `child_id` | string | Child ID |
+| `points` | int | Points value (positive = add, negative = remove) |
+| `reason` | string | Reason description |
+| `created_at` | string | ISO datetime |
+
+(v6.0.0) The feed also carries up to 8 recent rejections that had a [reason](Reject-Reasons.md) — `type` is `chore_rejected` or `reward_rejected`, with `chore_id`/`chore_name` or `reward_id`/`reward_name` and `reason` — and up to 8 [inspection](Surprise-Inspections.md) entries: `type` is `inspection_started`, `inspection_passed` (only when it paid no bonus; a bonus shows as its own points entry), `inspection_failed` or `inspection_redo`, with `chore_id`, `chore_name` and an optional `note`.
+
+### `active_timed_sessions` Array
+
+Active or paused timed task sessions:
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `chore_id` | string | Chore ID |
+| `child_id` | string | Child ID |
+| `state` | string | `running` or `paused` |
+| `total_seconds_today` | int | Cumulative elapsed seconds today |
+| `current_segment_start` | string\|null | ISO datetime of current running segment start |
+
+---
+
+## sensor.taskmate_pending_approvals
+
+Numeric count of total pending items.
+
+| Property | Value |
+|----------|-------|
+| State | Integer — total pending items |
+| State class | `measurement` |
+| Icon | `mdi:clipboard-clock` |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `pending_chore_completions` | int | Count of chores awaiting approval |
+| `pending_reward_claims` | int | Count of reward claims awaiting approval |
+| `pending_mandatory_misses` | int | Count of unresolved [mandatory-miss](Mandatory-Chores.md) review items |
+| `chore_completions` | list | Full details of pending chore completions |
+| `reward_claims` | list | Full details of pending reward claims |
+| `mandatory_misses` | list | Unresolved mandatory-miss review items (see below). See [Mandatory Chores](Mandatory-Chores.md) |
+| `quality_rating` | object | (v6.0.0) Present only while [quality ratings](Quality-Ratings.md) are on: `multipliers`, a list of the three star multipliers (★, ★★, ★★★). Approval cards use it to draw the star picker |
+
+**`chore_completions` entries:**
+
+| Field | Description |
+|-------|-------------|
+| `completion_id` | Completion ID (use with `approve_chore` / `reject_chore`) |
+| `type` | Always `"chore"` |
+| `child_name` | Child display name |
+| `child_id` | Child ID |
+| `chore_name` | Chore display name |
+| `chore_id` | Chore ID |
+| `points` | Points value |
+| `time_category` | Time of day |
+| `completed_at` | ISO datetime |
+| `bounty_id` | (v6.0.0) Present when the completion is a finished [bounty](Bounty-Board.md) |
+| `quantity` / `quantity_unit` | (v7.0.0) How many units were done on a [quantity chore](Quantity-Chores.md), e.g. `12` and `pages`, so you can see what is being paid for |
+| `reference_image_url` | (v7.0.0) A signed link to the chore's [reference photo](Reference-Photos.md) — what the job looks like done well — shown beside the child's evidence photo. Present only when the chore has one |
+
+**`reward_claims` entries:**
+
+| Field | Description |
+|-------|-------------|
+| `claim_id` | Claim ID (use with `approve_reward` / `reject_reward`) |
+| `type` | Always `"reward"` |
+| `child_name` | Child display name |
+| `child_id` | Child ID |
+| `reward_name` | Reward display name |
+| `reward_id` | Reward ID |
+| `cost` | Points cost |
+| `claimed_at` | ISO datetime |
+
+**`mandatory_misses` entries:**
+
+A pending [mandatory chore](Mandatory-Chores.md) miss, one per chore/child/day. Resolve with `apply_mandatory_penalty`, `postpone_mandatory_chore`, or `dismiss_mandatory_chore` (see [Services](Services.md#mandatory-chore-review-services-v420)).
+
+| Field | Description |
+|-------|-------------|
+| `id` | Miss ID (use with the mandatory-miss services as `miss_id`) |
+| `chore_id` | Chore ID |
+| `child_id` | Child ID |
+| `chore_name` | Chore display name |
+| `child_name` | Child display name |
+| `due_date` | ISO date the chore was missed |
+| `period_id` | The time-of-day period whose window closed (`anytime` for an all-day chore) |
+| `penalty_points` | Penalty snapshotted at miss time (applied by `apply_mandatory_penalty`) |
+| `postpone_count` | How many times this miss has been postponed |
+| `created_at` | ISO datetime the miss was recorded |
+
+---
+
+## sensor.taskmate_chores
+
+Chore definitions and today's completions.
+
+| Property | Value |
+|----------|-------|
+| State | Number of defined chores |
+| Icon | `mdi:format-list-checks` |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `chores` | list | Full chore definitions (see `chores` array above) |
+| `todays_completions` | list | Completions logged today (see `todays_completions` array above) |
+| `task_groups` | list | Task group definitions — each has `id`, `name`, `policy`, `chore_ids`. See [Task Groups](Task-Groups.md) |
+| `active_timed_sessions` | list | Running/paused timed sessions (see `active_timed_sessions` array below) |
+| `vacation_active` | bool | `true` if a [vacation period](Vacation-Mode.md) covers today |
+| `vacation_name` | string | Name of the active vacation period (empty when none) |
+| `vacation_end` | string | ISO end date of the active vacation period (empty when none) |
+
+---
+
+## sensor.taskmate_chore_availability
+
+Per-chore per-child availability matrix. Split from the chores sensor to keep payloads compact.
+
+| Property | Value |
+|----------|-------|
+| State | Count of available chore/child combinations |
+| Icon | `mdi:calendar-check` |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `chore_availability` | dict | `{chore_id: {child_id: bool}}` — whether each chore is available for each child today |
+
+---
+
+## sensor.taskmate_rewards
+
+Rewards catalogue, pending claims, and pool allocations.
+
+| Property | Value |
+|----------|-------|
+| State | Number of defined rewards |
+| Icon | `mdi:gift-outline` |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `rewards` | list | Full reward definitions (see `rewards` array above) |
+| `pending_reward_claims` | list | Pending reward claims (see `pending_reward_claims` array above) |
+| `pool_allocations` | list | Raw pool allocation records |
+| `raffles` | list | (v7.0.0) Open [raffles](Raffles.md) and those drawn or called off in the last 24 hours. Each has `id`, `name`, `prize`, `icon`, `cost` (ticket price), `draw_at`, `status` (`open` / `drawn` / `cancelled`), `tickets` (`{child_id: count}`), `total`, plus `max` (tickets per child) and `assigned_to` when set, and `winner_id` / `drawn_at` once drawn. Present only when there is one. Not recorded in history |
+
+---
+
+## sensor.taskmate_activity
+
+Recent completion and transaction history.
+
+| Property | Value |
+|----------|-------|
+| State | Total number of all-time completions |
+| Icon | `mdi:history` |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `recent_completions` | list | Up to 35 most recent completions (see `recent_completions` array above) |
+| `recent_transactions` | list | Up to 20 most recent point adjustments and reward events (see `recent_transactions` array above) |
+| `career_score_history` | dict | `{child_id: [...]}` — recorded career-score snapshots per child, for trend charts |
+| `photo_gallery` | list | (v4.4.0) Recent completions carrying a [photo proof](Photo-Proof.md) (newest first, up to 40) — each has `completion_id`, `child_name`, `chore_name`, `approved`, `completed_at`, `photo_url` (raw unsigned `/api/taskmate/photo/` path) |
+
+---
+
+## sensor.taskmate_incentives
+
+Penalties and bonuses catalogue.
+
+| Property | Value |
+|----------|-------|
+| State | Total number of penalties + bonuses |
+| Icon | `mdi:scale-balance` |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `penalties` | list | Penalty definitions — each has `id`, `name`, `points`, `description`, `icon`, `assigned_to` |
+| `bonuses` | list | Bonus definitions — each has `id`, `name`, `points`, `description`, `icon`, `assigned_to` |
+
+> **Note:** `task_groups` is published on [`sensor.taskmate_chores`](#sensortaskmate_chores), not on the incentives sensor.
+
+---
+
+## sensor.taskmate_bounties
+
+(v6.0.0) The [bounty board](Bounty-Board.md).
+
+| Property | Value |
+|----------|-------|
+| State | Number of open (unclaimed) bounties |
+| Icon | `mdi:flag-checkered` |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `bounties` | list | Live bounties plus those completed in the last 24 hours. Expired bounties and older history stay in the admin panel |
+
+**`bounties` entries** (optional fields appear only when set):
+
+| Field | Type | Description |
+|-------|------|-------------|
+| `id` | string | Bounty ID (use with the [bounty services](Services.md#bounty-services-v600)) |
+| `title` | string | What the job is |
+| `points` | int | Points paid on approval |
+| `icon` | string | MDI icon |
+| `status` | string | `open` / `claimed` / `pending` (done, waiting for approval) / `completed` |
+| `claim_hours` | int | How long a claim lasts |
+| `description` | string | Extra detail |
+| `eligible` | list | Child IDs who may claim it (absent = every child) |
+| `expires_at` | string | ISO datetime the bounty leaves the board if unclaimed |
+| `require_photo` | bool | A photo is needed to finish it |
+| `claimed_by` | string | Child ID holding the claim |
+| `claimed_at` / `claim_until` | string | ISO datetimes the claim started and runs out |
+| `completion_id` | string | The finished job's completion ID, for `approve_chore` / `reject_chore` |
+| `undo` | bool | The child may still take back their submission (see [Child Undo Window](Child-Undo-Window.md)) |
+| `points_awarded` / `completed_at` | int / string | On a completed bounty: what was paid, and when |
+
+---
+
+## sensor.taskmate_auctions
+
+(v6.0.0) [Chore auctions](Chore-Auctions.md). Bids are secret, so this sensor never shows who bid or how much — only how many bids are in, and the result once an auction closes.
+
+| Property | Value |
+|----------|-------|
+| State | Number of open auctions |
+| Icon | `mdi:gavel` |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `auctions` | list | Open auctions plus those closed in the last 24 hours — each has `id`, `chore_id`, `occurrence` (ISO date of the chore being auctioned), `closes_at`, `status` (`open` / `closed`), `bids` (count), `eligible` (child IDs), and once closed `winner_id` (empty when nobody bid) and `price` |
+
+---
+
+## sensor.taskmate_chore_board
+
+(v6.1.0) Today's chore board for every child: the same data as the admin panel's **Today** page, readable by any user. Feeds the [Chore Board card](Dashboard-Cards.md#chore-board-card).
+
+| Property | Value |
+|----------|-------|
+| State | Number of chores still to do today, across all children |
+| Icon | `mdi:view-grid-outline` |
+
+The state is handy in automations, e.g. a bedtime announcement when it isn't `0`.
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `chore_board` | object | Today's board (time periods, and each child's chores with their status: done, awaiting approval, to do or missed) plus the last 7 days' done/total per child. Rebuilt at midnight. Not recorded in history |
+
+---
+
+## Per-Child Sensors
+
+Each child gets two sensors:
+
+**`sensor.{child_name}_points`** — State: current gross points balance. State class: `total`.
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `child_id` | string | Child ID |
+| `child_name` | string | Display name |
+| `avatar` | string | MDI icon |
+| `avatar_image` | string | (v6.4.0) The child's [photo](Children.md#child-photos), or empty |
+| `total_points_earned` | int | Lifetime points earned |
+| `total_chores_completed` | int | Lifetime completions |
+| `current_streak` | int | Current consecutive day streak |
+| `best_streak` | int | Best streak ever |
+| `career_score` | int | Long-term score (`total_points_earned − total_penalties_received`) |
+
+**`sensor.{child_name}_stats`** — State: total chores completed. State class: `total`. From v6.4.0 its entity picture is the child's [photo](Children.md#child-photos) when they have one.
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `child_id` | string | Child ID |
+| `child_name` | string | Display name |
+| `avatar` | string | MDI icon |
+| `avatar_image` | string | (v6.4.0) The child's [photo](Children.md#child-photos), or empty |
+| `points` | int | Current points balance |
+| `total_points_earned` | int | Lifetime points earned |
+| `total_chores_completed` | int | Lifetime completions |
+| `current_streak` | int | Current streak |
+| `best_streak` | int | Best streak |
+| `career_score` | int | Long-term score |
+| `total_penalties_received` | int | Lifetime penalties applied |
+| `assigned_chores` | list | Chores assigned to this child today (each has `id`, `name`, `points`, `time_category`) |
+| `chore_order` | list | Custom chore display order |
+
+---
+
+## Per-Child Wishlist Sensors
+
+(v6.0.0) **`sensor.taskmate_{child_slug}_wishlist`** — one per child, for the [Wishlist](Wishlist.md) card. State: wishes on the go (waiting for approval, saving, or waiting to be handed over). Icon `mdi:heart-outline`.
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `wishlist_child_id` | string | The child this sensor belongs to (the card finds its sensor by this) |
+| `wish_max_open` | int | Most wishes a child can have on the go (5) |
+| `wishes` | list | The child's wishes, except redeemed ones |
+
+**`wishes` entries** (optional fields appear only when set): `id`, `name`, `target`, `status` (`pending` / `active` / `redeem_requested` / `declined`), `saved` (the child's own points in it), `pledged` (total pledged), `pledges` (one `{name, points}` chip per person, largest first), `link`, `image_url`, `decline_reason`.
+
+---
+
+## Per-Child Watch Sensors
+
+(v6.0.0) **`sensor.taskmate_{child_slug}_watch`** — a child's day in a few characters, sized for Apple Watch and Wear OS complications. See [Watch Complications](Watch-Complications.md). Icon `mdi:watch`.
+
+**State:** a short phrase in Home Assistant's language — `3 left`, `All done` or `No chores`.
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `child_id` | string | Child ID |
+| `status` | string | `to_do` / `all_done` / `no_chores` — language-independent, for templates |
+| `left` | int | Chores still owed today (including ones that need a photo or a timer) |
+| `done` | int | Chores done today, approved or waiting for approval |
+| `total` | int | Chores due today |
+| `progress` | float | `done / total`, 0–1 (1.0 when nothing was due) — for gauge and ring complications |
+| `points` | int | Current points balance |
+| `streak` | int | Current streak |
+| `next_chore` | string | The chore [`complete_next_chore`](Services.md#taskmatecomplete_next_chore-v600) would complete (up to 40 characters). Absent when nothing is left, or only chores that need a photo, note, timer or team remain |
+
+---
+
+## Per-Child Badge Sensors
+
+**`sensor.taskmate_{child_slug}_badges`** — State: count of earned badges.
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `earned` | list | Array of earned badge objects, each with `badge_id`, `name`, `icon`, `tier`, `earned_at`, `manually_awarded` (bool), `silent` (bool) |
+| `available` | list | Array of not-yet-earned applicable badges, each with `badge_id`, `name`, `icon`, `tier`, `progress_pct`, `criteria_summary` |
+| `total_badges` | int | Number of badges applicable to this child (earned + locked) |
+| `child_name` | string | (v6.4.0) Whose badges these are |
+| `child_avatar` | string | (v6.4.0) The child's MDI icon |
+| `avatar_image` | string | (v6.4.0) The child's [photo](Children.md#child-photos), or empty |
+
+See [Achievement Badges](Achievement-Badges.md) for full details.
+
+---
+
+## binary_sensor.taskmate_has_pending_approvals
+
+Simple on/off sensor for use in automations and notifications.
+
+| Property | Value |
+|----------|-------|
+| `on` | There are pending chore completions **or** reward claims |
+| `off` | Nothing pending |
+| Icon (on) | `mdi:bell-alert` |
+| Icon (off) | `mdi:bell-check` |
+| Device class | None |
+
+### Attributes
+
+| Attribute | Type | Description |
+|-----------|------|-------------|
+| `pending_chore_completions` | int | Count of chores pending |
+| `pending_reward_claims` | int | Count of reward claims pending |
+| `total_pending` | int | Combined total |
+
+---
+
+## Button Entities
+
+One button entity per child/chore combination and per child/reward combination. Since v6.0.0, deleting a chore, reward or child removes its buttons, and buttons left behind by earlier deletions are cleaned up on start-up:
+
+| Entity | Action |
+|--------|--------|
+| `button.{child}_complete_{chore}` | Complete the chore for the child |
+| `button.{child}_claim_{reward}` | Claim the reward for the child |
+
+The reward claim button is only `available` (not greyed out) when the child has enough points.
+
+---
+
+## Calendar Entities (v4.2.0)
+
+One calendar entity per child, created by the calendar platform and added automatically as children are created:
+
+| Entity | Description |
+|--------|-------------|
+| `calendar.taskmate_` | Friendly name `TaskMate ` (icon `mdi:calendar-account`). Projects the child's upcoming chore occurrences from the recurrence/assignment engine — timed events inside the chore's time-of-day window, or all-day events for `anytime` chores. [Away](Vacation-Mode.md) periods appear as coalesced multi-day "Away" all-day events (chores are hidden on away days). The entity state is the current or next upcoming event. |
+
+(v6.0.0) Parents and admins can also **edit** these calendars in Home Assistant's calendar: creating an event makes a one-off chore on that day, moving one occurrence shifts just that day, and deleting one occurrence skips it. Moving a whole series, or moving into the past, is refused. Completing a chore from the calendar is not supported. See [Two-Way Calendar](Two-Way-Calendar.md) and [Calendar](Calendar.md).
+
+---
+
+## To-Do Entities (v4.4.0)
+
+One to-do list entity per child, created by the `todo` platform and added automatically as children are created:
+
+| Entity | Description |
+|--------|-------------|
+| `todo.taskmate_` | Friendly name = the child's name. Lists the chores the child still needs to do today. Checking an item off **completes** that chore for the child — so the native HA to-do card and voice assistants can drive TaskMate without the custom cards. Supports the `UPDATE_TODO_ITEM` feature only (no add/delete). |
+
+See [Configuration Entities](Configuration-Entities.md).
+
+---
+
+## Configuration Entities (v4.4.0)
+
+Key settings are surfaced as `number` and `select` entities so they can be read and changed from automations, scripts, and the HA UI without a service call. Values persist through the same settings store the admin panel uses, so panel and entity stay in sync.
+
+| Entity | Type | Range / Options | Default | Setting |
+|--------|------|-----------------|---------|---------|
+| `number.taskmate_weekend_multiplier` | number | 1.0–5.0 (step 0.5) | 1.0 | `weekend_multiplier` |
+| `number.taskmate_perfect_week_bonus` | number | 0–1000 (step 1) | 0 | `perfect_week_bonus` |
+| `select.taskmate_streak_reset_mode` | select | `reset` / `pause` | `reset` | `streak_reset_mode` |
+| `select.taskmate_card_design` | select | `classic` / `playroom` / `console` / `cleanpro` / `accessible` | `classic` | `card_design` |
+
+See [Configuration Entities](Configuration-Entities.md) and [Settings](Settings.md).
+
+---
+
+## Event Entities (v7.0.0)
+
+TaskMate's [bus events](Automations.md#bus-events-reference) are also published as event entities, so they can be picked in the UI automation editor and shown on a dashboard. See [Event Entities](Event-Entities.md).
+
+| Entity | Description |
+|--------|-------------|
+| `event.taskmate__activity` | One per child (friendly name ` activity`). Fires for that child's moments: `chore_completed`, `chore_approved`, `chore_rejected`, `chore_approval_undone`, `chore_auto_approved`, `reward_claimed`, `reward_approved`, `reward_rejected`, `badge_earned`, `level_up`, `streak_updated`, `streak_freeze_used`, `perfect_week`, `weekly_target_reached`, `weekly_goal_reached`, `quest_completed`, `challenge_completed`, `bonus_applied`, `penalty_applied`, `penalty_redeemed`, `surprise_bonus`, `mandatory_missed`, `team_chore_completed`, `points_gifted`, `help_requested`, `mood_logged`, `sick_day`, `raffle_won`, `pet_evolved` |
+| `event.taskmate_family_activity` | One for the family (friendly name `Family activity`). Fires for `family_goal_reached`, `season_champion`, `bounty_posted`, `scheduled_change_applied`, `raffle_drawn` |
+
+The state is the time of the latest event; the `event_type` attribute says which one, and the event's own data (child, chore, points and so on) is copied onto the entity as attributes. A gift shows on both children's entities, and a teamwork chore on every team member's.
+
+---
+
+## Admin-Panel-Only Data (not entity attributes)
+
+Some v4.0.0 data is served to the [Admin Panel](Admin-Panel.md) over the websocket API rather than exposed as sensor attributes:
+
+| Data | Where | Notes |
+|------|-------|-------|
+| Quest **definitions** | websocket state `quests` / `quest_progress` | Per-child quest progress is mirrored into the overview `children[].quests`. See [Quests](Quests.md) |
+| Challenge **definitions** | websocket state `challenges` | Per-child progress is mirrored into `children[].challenges`. See [Challenges](Challenges.md) |
+| Avatar **catalogue** | websocket state `avatar_catalog` | Per-child unlock state is mirrored into `children[].avatar_options`. See [Avatars](Avatars.md) |
+| **Swap requests** | websocket state `swap_requests` | Pending [chore swap](Chore-Swaps.md) requests awaiting parent action |
+| **Audit log** | websocket commands `taskmate/audit/list` + `/clear`; initial state `audit_log` (newest 100) | See [Admin Audit Log](Admin-Audit-Log.md) |
+| **Auction bids** | websocket `taskmate/auctions/list` | (v6.0.0) A child only ever gets their own bid back. See [Chore Auctions](Chore-Auctions.md) |
+| **Recaps** | websocket `taskmate/recaps/list` + `/get` | (v6.0.0) Stored [recaps](Recaps.md) per child, read by the recap card |
+| **Kiosk PINs** | websocket `taskmate/kiosk/status` | (v6.0.0) Only whether a child has a PIN; PINs are stored hashed. See [Kiosk Mode](Kiosk-Mode.md) |
+| **Raffles** | websocket `taskmate/raffles/list` | (v7.0.0) Every raffle, including old ones, for the panel's **Raffles** tab. Cards read open and recent raffles from `sensor.taskmate_rewards` |
+| **Moods** | websocket `taskmate/reports/moods` | (v7.0.0) Each child's moods for the last 14 days (up to 90), for **Insights → Moods**. See [Mood Check-In](Mood-Check-In.md) |
+
+---
+
+## Sensor Update Frequency
+
+The coordinator polls every **30 seconds**. All entities update together. Completions, approvals, and point changes trigger an immediate refresh.
diff --git a/wiki/Services.md b/wiki/Services.md
new file mode 100644
index 00000000..2d8b8177
--- /dev/null
+++ b/wiki/Services.md
@@ -0,0 +1,1151 @@
+# Services
+
+TaskMate exposes a set of Home Assistant services for automations, scripts, and custom frontend integrations.
+
+Every service is in the `taskmate.*` namespace and accepts parameters via the standard `service_data` / `data` key.
+
+## Dynamic Selectors (v3.7.0+)
+
+All entity ID fields (`child_id`, `chore_id`, `reward_id`, `penalty_id`, `bonus_id`, `group_id`) show as **dropdown selectors** in the HA automation editor and Developer Tools → Services. The dropdown lists entity names as labels with the hex IDs as values, so you can pick "Noah" instead of typing `ef19c56175c14bd9`.
+
+- Dropdowns refresh automatically every 30 seconds as entities are added or removed
+- `custom_value` mode is enabled — you can still type a raw hex ID if you prefer
+- Services without entity ID fields (e.g. `preview_sound`, `add_chore`) are unaffected
+- Uses Home Assistant's native select widget — no custom styling
+
+> **Tip:** If you need to find an ID outside the automation editor, enable the [Show IDs toggle](Admin-Panel.md#show-ids-v370) in the admin panel.
+
+---
+
+## Chore services
+
+### `taskmate.complete_chore`
+Mark a chore as completed by a child.
+
+| Field | Required | Default | Description |
+| --- | --- | --- | --- |
+| `chore_id` | ✅ | — | ID of the chore |
+| `child_id` | ✅ | — | ID of the child |
+| `as_parent` | | `false` | Complete on behalf of the child and award points immediately, bypassing approval (v4.0.0, #402). See [Photo Proof](Photo-Proof.md) for how this interacts with photo-required chores. |
+| `photo_url` | | — | Optional evidence photo URL/path attached to the completion. Required in spirit when the chore has [photo proof](Photo-Proof.md) enabled. |
+| `note` | | — | The child's own description of what they did (v5.7.0, #832). **Required** when the chore is [open-ended](Open-Ended-Chores.md). Trimmed to 200 characters. |
+| `suggested_points` | | `0` | What the child reckons the work was worth (v5.7.0, #832). A hint for the approving parent — it awards nothing on its own. Clamped to 0–999. |
+| `quantity` | | — | (v7.0.0) How many units the child did on a [quantity chore](Quantity-Chores.md) ("read 20 pages"), 0–10000. Required from a child on those chores; the chore's points are paid per unit, capped at the chore's maximum. Ignored on other chores. |
+| `completed_date` | | — | (v6.4.0) Log the job for an earlier day that was done but not ticked: up to 7 days back, not today. Parents only (an HA admin or a [TaskMate parent](Parent-Access.md); automations are allowed). Approved straight away and left out of the streak. See [Logging Past Jobs](Logging-Past-Jobs.md). |
+
+```yaml
+service: taskmate.complete_chore
+data:
+ chore_id: 8a3b2c1d4e5f6789
+ child_id: ef19c56175c14bd9
+ as_parent: false
+ photo_url: "/local/proof/dishes.jpg"
+```
+
+> **Note:** `as_parent: true` records the completion under the parent (`__parent__`) and skips the approval queue. A chore with `require_photo` enabled always routes to approval so the photo can be reviewed.
+
+Logging a job done on an earlier day (v6.4.0):
+
+```yaml
+service: taskmate.complete_chore
+data:
+ chore_id: 8a3b2c1d4e5f6789
+ child_id: ef19c56175c14bd9
+ completed_date: "2026-10-13"
+```
+
+The day's daily limit and the week's [weekly target](Weekly-Targets.md) still apply. The call is refused, with a message saying why, for a day the chore wasn't due, a vacation day, a rotation, teamwork or open-ended chore, or a day it was won at auction. An [adult profile](Adult-Profiles.md)'s own completions are always approved straight away, with or without `completed_date`.
+
+### `taskmate.approve_chore`
+Approve a completed chore and award points.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `completion_id` | ✅ | ID of the pending chore completion |
+| `points` | ❌ | Award this many points instead of the chore's own value (v5.7.0, #832). Replaces the **base** points, so the multipliers below still apply on top. Omit to use the chore's value. |
+| `rating` | ❌ | (v6.0.0) A 1–3 star [quality rating](Quality-Ratings.md). When quality ratings are switched on in Settings, the points are scaled by that star's multiplier (by default ★ 75%, ★★ 100%, ★★★ 125%). Leave it out to pay 100%. Ignored while quality ratings are off. |
+
+```yaml
+service: taskmate.approve_chore
+data:
+ completion_id: 4f21b8e0c7a94d13
+ points: 15
+ rating: 3
+```
+
+Also accepted by the `taskmate/approve_chore` WebSocket command, which is what the review-and-award sheet on the [Approvals Card](Approvals-Card.md) calls. `approve_all_chores` never overrides — a bulk approval always uses each chore's own points.
+
+### `taskmate.approve_all_chores` (v4.4.3+)
+Approve every pending chore completion at once — or a specific set — and award points. Each approval runs the same award/badge/quest/streak/celebration side-effects as [`approve_chore`](#approve_chore). Admin-only.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `completion_ids` | ❌ | List of specific completion IDs to approve. Omit to approve **all** currently-pending completions. IDs not currently pending are skipped. |
+| `rating` | ❌ | (v6.0.0) A 1–3 star [quality rating](Quality-Ratings.md) applied to every chore approved by this call. Needs quality ratings switched on in Settings. |
+
+Also exposed as the `taskmate/approve_all_chores` WebSocket command (same optional `completion_ids`), returning `{ "count": }`. This is what the **Approve All** buttons on the panel and [Approvals Card](Approvals-Card.md) call.
+
+### `taskmate.reject_chore`
+Reject a completed chore. No points awarded.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `completion_id` | ✅ | ID of the pending chore completion |
+| `reason` | ❌ | (v6.0.0) Why it was sent back, up to 200 characters. The child sees "Sent back: …" on their card for 24 hours, and it is included in the `taskmate_chore_rejected` event and the optional **Item rejected** notification. See [Reject Reasons](Reject-Reasons.md). |
+
+```yaml
+service: taskmate.reject_chore
+data:
+ completion_id: 4f21b8e0c7a94d13
+ reason: "Not finished — the bottom shelf is still messy"
+```
+
+### `taskmate.undo_chore` (v6.0.0)
+Lets a **child** take back their own chore. Off until **Settings → Child undo window (seconds)** is set above `0`. See [Child Undo Window](Child-Undo-Window.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `completion_id` | ✅ | ID of the child's chore completion |
+
+- A submission still **waiting for approval** can be withdrawn until a parent reviews it.
+- An **automatically approved** chore (no approval needed) can be undone within the window.
+- Once a parent has reviewed it, only a parent can undo it (with `reject_chore` or `undo_chore_approval`).
+- The child is taken from the stored completion, never from the call, so one child can't undo a sibling's chore when "Require a linked account per child" is on.
+
+Fires `taskmate_chore_undone` (not `taskmate_chore_rejected`), so automations can tell a child's own undo from a parent's rejection.
+
+### `taskmate.add_chore`
+Create a chore dynamically (for automations).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `name` | ✅ | Chore title |
+| `description` | | Optional details |
+| `points` | | Point value (default 10) |
+| `assigned_to` | | List of child IDs (empty = all) |
+| `time_category` | | `morning` / `afternoon` / `evening` / `night` / `anytime` (default `anytime`) |
+| `difficulty` | | Difficulty tier — `easy` / `medium` / `hard` (default `medium`). Scales awarded points by the tier multiplier; `medium` = ×1.0 baseline. See [Difficulty Tiers](Difficulty-Tiers.md). |
+| `one_shot` | | Single-day auto-expiring chore (boolean, default false) |
+| `requires_approval` | | Parent approval required (boolean, default true) |
+| `expires_in_minutes` | | (v5.0.0) Deadline this many minutes from now — makes it a [reactive chore](Reactive-Chores.md). `0` = no deadline. Max 10080 (a week). A chore with a deadline is automatically one-shot. |
+| `speed_bonus_points` | | (v5.0.0) Extra points if the chore is completed before the deadline |
+| `team_size` | | (v6.0.0) Make it a [teamwork chore](Teamwork-Chores.md) that only counts once this many children (2–10) have joined. `0` = a normal chore (default) |
+| `team_points_mode` | | (v6.0.0) `each` (everyone gets the full points, default) or `split` (the points are divided evenly, rounded down) |
+| `team_bonus` | | (v6.0.0) Extra points each team member earns when the team completes the chore (default 0) |
+
+```yaml
+service: taskmate.add_chore
+data:
+ name: "Take out recycling"
+ points: 15
+ difficulty: hard
+ time_category: evening
+ assigned_to:
+ - ef19c56175c14bd9
+```
+
+> **Note:** Some advanced chore fields — `expires_on`, photo proof (`require_photo`), time incentives (`due_time` / `early_bonus` / `late_penalty`), weather conditions, and `first_come` assignment mode — are not exposed on the `add_chore` service. Configure them in the [Admin Panel](Admin-Panel.md) chore editor. See [Difficulty Tiers](Difficulty-Tiers.md), [Photo Proof](Photo-Proof.md), and [Chores](Chores.md).
+
+### `taskmate.skip_chore`
+Skip today's assigned child in a rotation-mode chore and reassign to the next child in the pool.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `chore_id` | ✅ | ID of the chore |
+
+Only works for non-`everyone` assignment modes with a pool of 2+ children. The skip is ephemeral — applies only today and resets at midnight. Maximum skips per day = pool size − 1. Sticky group followers cannot be skipped individually.
+
+### `taskmate.set_chore_manual_start`
+Override the rotation to start with a specific child.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `chore_id` | ✅ | ID of the chore |
+| `child_id` | ✅ | ID of the child to assign |
+
+For `alternating` mode: reorders the rotation so the chosen child is first and resets the anchor to today. For `random`/`balanced` modes: overrides today's cached assignment only — the deterministic algorithm resumes tomorrow. Clears any active skip state.
+
+### `taskmate.complete_bonus_subtask`
+Complete a bonus subtask within a parent chore.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `chore_id` | ✅ | ID of the parent chore |
+| `bonus_subtask_id` | ✅ | ID of the bonus subtask |
+| `child_id` | ✅ | ID of the child |
+
+The parent chore must already be completed by the same child today. The subtask cannot already be completed by that child today. See [Bonus Subtasks](Bonus-Subtasks.md).
+
+### `taskmate.request_swap` (v4.0.0)
+A child requests to take over today's rotation assignment of a chore. Creates a pending swap request for a parent to approve. See [Chore Swaps](Chore-Swaps.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `chore_id` | ✅ | ID of the chore (must be a rotation mode: `alternating` / `random` / `balanced` / `first_come`) |
+| `requester_id` | ✅ | ID of the child requesting to take the chore over |
+
+```yaml
+service: taskmate.request_swap
+data:
+ chore_id: 8a3b2c1d4e5f6789
+ requester_id: ef19c56175c14bd9
+```
+
+The requester must be a different child from today's current assignee and must be in the chore's pool. Approve/reject the request from the Admin Panel; on approval the chore's `assignment_current_child_id` is set to the requester. See [Chore Swaps](Chore-Swaps.md).
+
+### `taskmate.leave_team_chore` (v6.0.0)
+Take a child back out of a [teamwork chore](Teamwork-Chores.md) they joined today, before the team is complete. (Joining is just a normal `complete_chore` on a teamwork chore.)
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `chore_id` | ✅ | ID of the teamwork chore |
+| `child_id` | ✅ | ID of the child leaving the team |
+
+A child can only leave for themselves; parents can remove anyone. Leaving a team you hadn't joined, or one that has already completed, does nothing.
+
+### `taskmate.complete_next_chore` (v6.0.0)
+Complete the child's **next** outstanding chore, in the order their child card shows. Made for a watch button or a phone shortcut. See [Watch Complications](Watch-Complications.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+
+```yaml
+service: taskmate.complete_next_chore
+data:
+ child_id: ef19c56175c14bd9
+```
+
+- Chores that need a photo, a note, a timer or a team are skipped.
+- Approval rules apply exactly as if the child had tapped the chore.
+- When nothing is left it quietly does nothing, rather than raising an error.
+
+## Timed task services
+
+### `taskmate.start_timed_task`
+Start or resume a timed task timer.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `chore_id` | ✅ | ID of the timed chore |
+| `child_id` | ✅ | ID of the child |
+
+Starts a new session or resumes a paused one. Checks the daily cap before starting.
+
+### `taskmate.pause_timed_task`
+Pause a running timed task timer.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `chore_id` | ✅ | ID of the timed chore |
+| `child_id` | ✅ | ID of the child |
+
+Closes the current time segment and marks the session as paused. Resume with `start_timed_task`.
+
+### `taskmate.stop_timed_task`
+Stop a timed task and submit for approval.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `chore_id` | ✅ | ID of the timed chore |
+| `child_id` | ✅ | ID of the child |
+
+Creates a completion record. Points are calculated as `floor(total_seconds / (rate_minutes × 60)) × rate_points`, clamped to the daily cap if set. See [Timed Tasks](Timed-Tasks.md).
+
+## Task group services
+
+### `taskmate.add_task_group`
+Create a task group to coordinate rotation-mode chore assignments.
+
+| Field | Required | Default | Description |
+| --- | --- | --- | --- |
+| `name` | ✅ | — | Group display name |
+| `policy` | ✅ | `sticky` | `sticky` (same child) or `spread` (different children) |
+| `chore_ids` | | `[]` | Ordered list of chore IDs |
+
+```yaml
+service: taskmate.add_task_group
+data:
+ name: "Dinner Duties"
+ policy: sticky
+ chore_ids:
+ - abc12345
+ - def67890
+```
+
+### `taskmate.update_task_group`
+Update an existing task group. Only supplied fields are changed.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `group_id` | ✅ | ID of the group to update |
+| `name` | | New name |
+| `policy` | | New policy |
+| `chore_ids` | | New ordered chore list |
+
+### `taskmate.remove_task_group`
+Delete a task group. Chores revert to independent rotation.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `group_id` | ✅ | ID of the group to remove |
+
+See [Task Groups](Task-Groups.md) for full details on sticky and spread policies.
+
+## Reward services
+
+### `taskmate.claim_reward`
+A child claims a reward. Creates a pending claim awaiting parent approval.
+
+For **wallet-mode** rewards: child's balance must cover the cost.
+For **pool-mode** rewards: the child's pool allocation must equal or exceed the cost (i.e. the pool is full).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `reward_id` | ✅ | ID of the reward |
+| `child_id` | ✅ | ID of the claiming child |
+
+### `taskmate.approve_reward`
+Approve a pending reward claim. For wallet rewards, deducts cost from the child's balance. For pool rewards, clears the allocation (points were already deducted at deposit time).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `claim_id` | ✅ | ID of the pending reward claim |
+
+### `taskmate.reject_reward`
+Reject a pending reward claim. For wallet rewards, no action (points were never deducted). For pool rewards, allocation stays in place — child can Redeem again.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `claim_id` | ✅ | ID of the pending reward claim |
+| `reason` | ❌ | (v6.0.0) Why the claim was turned down, up to 200 characters. Shown to the child and included in the `taskmate_reward_rejected` event. See [Reject Reasons](Reject-Reasons.md). |
+
+### `taskmate.allocate_points_to_pool` (v3.0+)
+Move points from a child's spendable balance into a specific reward's pool.
+
+Allocations are **locked** — there is no matching withdraw service. The requested amount is silently capped at whichever is lowest:
+- The requested `points`
+- The child's current spendable balance
+- The pool's remaining capacity (`reward.cost − already_allocated`)
+
+Logs a negative `PointsTransaction` for audit.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child making the deposit |
+| `reward_id` | ✅ | ID of the reward pool |
+| `points` | ✅ | Points to allocate (integer ≥ 1) |
+
+**Example:**
+```yaml
+service: taskmate.allocate_points_to_pool
+data:
+ child_id: 8a3b2c1d4e5f6789
+ reward_id: 1f2e3d4c5b6a7890
+ points: 5
+```
+
+**Errors:**
+- `ValueError: No spendable points available` — child has no uncommitted points
+- `ValueError: Pool for reward 'X' is already full`
+- `ValueError: Points to allocate must be at least 1`
+
+## Points services
+
+### `taskmate.add_points`
+Add bonus points to a child.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+| `points` | ✅ | Points to add |
+| `reason` | | Optional reason logged to activity |
+
+### `taskmate.remove_points`
+Remove points from a child.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+| `points` | ✅ | Points to remove |
+| `reason` | | Optional reason |
+
+### `taskmate.gift_points` (v4.0.0)
+Transfer spendable points from one child to another (parent-controlled). See [Gifting Points](Gifting-Points.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `from_child_id` | ✅ | ID of the sending child |
+| `to_child_id` | ✅ | ID of the receiving child |
+| `points` | ✅ | Points to transfer (integer ≥ 1) |
+
+```yaml
+service: taskmate.gift_points
+data:
+ from_child_id: ef19c56175c14bd9
+ to_child_id: 8a3b2c1d4e5f6789
+ points: 10
+```
+
+Deducts from the sender's spendable balance and credits the recipient. Logs a `PointsTransaction` on both children (`Gift to ` / `Gift from `). The gift does **not** count toward the recipient's `total_points_earned` or career score, and the spending cap does not apply. Sender and recipient must differ, and the sender must hold at least `points`. See [Gifting Points](Gifting-Points.md).
+
+### `taskmate.undo_transaction` (v4.0.0)
+Reverse a reversible points transaction by its ID — penalties, bonuses, manual add/remove adjustments, and gifts (both legs). Automatic transactions (weekend/streak/perfect-week bonuses, pool moves, decay, interest) cannot be undone. See [Points Economy](Points-Economy.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `transaction_id` | ✅ | ID of the points transaction to reverse (from the activity feed / `recent_transactions`) |
+
+```yaml
+service: taskmate.undo_transaction
+data:
+ transaction_id: 3f2e1d0c9b8a7654
+```
+
+Re-credits (for a penalty) or re-debits (for a bonus) the original amount and removes the transaction record. Undoing a gift reverses both legs (sender re-credited, recipient re-debited). See [Points Economy](Points-Economy.md).
+
+### `taskmate.undo_chore_approval` (v4.1.0)
+Reverse an accidental chore approval — removes the awarded points and returns the completion to pending so it can be approved (or rejected) again. See [Points Economy](Points-Economy.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `completion_id` | ✅ | ID of the approved chore completion to revert to pending |
+
+```yaml
+service: taskmate.undo_chore_approval
+data:
+ completion_id: 9c8b7a6d5e4f3210
+```
+
+Removes the points credited at approval, reverses the associated `PointsTransaction`, and moves the completion back into the pending-approvals queue. See [Points Economy](Points-Economy.md).
+
+### `taskmate.record_allowance_payout` (v4.4.0)
+Convert a child's points into a real-money allowance payout — deducts the points and records the payout in the allowance ledger at the configured fixed conversion rate. Parent-controlled and audit-logged. See [Allowance](Allowance.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+| `points` | ✅ | Points to convert to cash and deduct (1–100000) |
+
+```yaml
+service: taskmate.record_allowance_payout
+data:
+ child_id: ef19c56175c14bd9
+ points: 100
+```
+
+Deducts `points` from the child (logging a `Allowance payout` `PointsTransaction`) and appends a ledger entry recording the cash `amount` (`points ÷ allowance_rate`, rounded to 2 dp) and `currency`. Requires [Allowance](Allowance.md) to be enabled (`allowance_enabled`); raises an error otherwise. Fires the `taskmate_allowance_paid` event. See [Allowance](Allowance.md).
+
+### `taskmate.adjust_streak_freezes` (v6.0.0)
+Give a child [streak freeze](Streak-Freezes.md) tokens, or take some away. Parent only.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+| `amount` | ✅ | Tokens to add (positive) or remove (negative), −10 to 10 |
+
+```yaml
+service: taskmate.adjust_streak_freezes
+data:
+ child_id: ef19c56175c14bd9
+ amount: 1
+```
+
+A grant never takes the child past **Max streak freezes**, and a removal never goes below zero. Granting is refused while streak freezes are switched off (max set to `0`).
+
+## Penalty services
+
+### `taskmate.add_penalty`
+Create a reusable penalty definition.
+
+| Field | Required | Default | Description |
+| --- | --- | --- | --- |
+| `name` | ✅ | — | Penalty name |
+| `points` | ✅ | — | Points to deduct when applied (1–10000) |
+| `description` | | `""` | Optional description |
+| `icon` | | `mdi:alert-circle-outline` | MDI icon |
+| `assigned_to` | | all children | List of child IDs this penalty applies to |
+
+### `taskmate.update_penalty`
+Update an existing penalty. Only supplied fields are changed.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `penalty_id` | ✅ | ID of the penalty to update |
+| `name` | | New name |
+| `points` | | New points value (1–10000) |
+| `description` | | New description |
+| `icon` | | New MDI icon |
+| `assigned_to` | | New child ID list |
+
+### `taskmate.remove_penalty`
+Delete a penalty definition.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `penalty_id` | ✅ | ID of the penalty to remove |
+
+### `taskmate.apply_penalty`
+Apply a penalty to a child — deducts points and logs a `PointsTransaction` to the activity feed.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `penalty_id` | ✅ | ID of the penalty to apply |
+| `child_id` | ✅ | ID of the child |
+
+> **Note:** A child's balance can go negative when a penalty is applied.
+
+## Mandatory chore review services (v4.2.0)
+
+When a [mandatory chore](Mandatory-Chores.md) is left incomplete and its time-period window closes, TaskMate records a **mandatory-miss** review item (one per chore/child/day). These services resolve a pending miss; each clears the review item. Find the `miss_id` in the `mandatory_misses` list on [`sensor.taskmate_pending_approvals`](Sensor-Reference.md#sensortaskmate_pending_approvals). See [Mandatory Chores](Mandatory-Chores.md).
+
+### `taskmate.apply_mandatory_penalty`
+Deduct the configured penalty points for a missed mandatory chore and clear the review item.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `miss_id` | ✅ | ID of the mandatory-miss review item |
+
+```yaml
+service: taskmate.apply_mandatory_penalty
+data:
+ miss_id: 4d3c2b1a0f9e8d7c
+```
+
+Deducts the miss's snapshotted `penalty_points` from the child (logging a `PointsTransaction`) when greater than 0, then removes the review item. See [Mandatory Chores](Mandatory-Chores.md).
+
+### `taskmate.postpone_mandatory_chore`
+Give a missed mandatory chore another period (or tomorrow) without a penalty, and clear the review item.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `miss_id` | ✅ | ID of the mandatory-miss review item |
+
+```yaml
+service: taskmate.postpone_mandatory_chore
+data:
+ miss_id: 4d3c2b1a0f9e8d7c
+```
+
+Re-opens the chore in the next remaining time period today; if no window is left today, normal scheduling resurfaces it tomorrow. No points are deducted. See [Mandatory Chores](Mandatory-Chores.md).
+
+### `taskmate.dismiss_mandatory_chore`
+Clear a missed mandatory chore review item with no penalty.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `miss_id` | ✅ | ID of the mandatory-miss review item |
+
+```yaml
+service: taskmate.dismiss_mandatory_chore
+data:
+ miss_id: 4d3c2b1a0f9e8d7c
+```
+
+Removes the review item outright — no points change, no rescheduling. See [Mandatory Chores](Mandatory-Chores.md).
+
+## Bonus services
+
+### `taskmate.add_bonus`
+Create a reusable bonus definition.
+
+| Field | Required | Default | Description |
+| --- | --- | --- | --- |
+| `name` | ✅ | — | Bonus name |
+| `points` | ✅ | — | Points to award when applied (1–10000) |
+| `description` | | `""` | Optional description |
+| `icon` | | `mdi:star-circle-outline` | MDI icon |
+| `assigned_to` | | all children | List of child IDs this bonus applies to |
+
+### `taskmate.update_bonus`
+Update an existing bonus. Only supplied fields are changed.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `bonus_id` | ✅ | ID of the bonus to update |
+| `name` | | New name |
+| `points` | | New points value (1–10000) |
+| `description` | | New description |
+| `icon` | | New MDI icon |
+| `assigned_to` | | New child ID list |
+
+### `taskmate.remove_bonus`
+Delete a bonus definition.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `bonus_id` | ✅ | ID of the bonus to remove |
+
+### `taskmate.apply_bonus`
+Apply a bonus to a child — awards points and logs a `PointsTransaction` to the activity feed.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `bonus_id` | ✅ | ID of the bonus to apply |
+| `child_id` | ✅ | ID of the child |
+
+## Badge services
+
+### `taskmate.add_badge`
+Create a custom badge with optional criteria and point bonus.
+
+| Field | Required | Default | Description |
+| --- | --- | --- | --- |
+| `name` | ✅ | — | Badge display name |
+| `description` | | `""` | Description text |
+| `icon` | | `mdi:medal` | MDI icon |
+| `tier` | | `bronze` | `bronze`, `silver`, `gold`, or `platinum` |
+| `point_bonus` | | `0` | Bonus points awarded when earned |
+| `criteria` | | `[]` | List of `{metric, operator, value}` objects — AND-evaluated |
+| `assigned_to` | | all children | List of child IDs (empty = all) |
+| `notify_on_earn` | | `true` | Fire notifications when earned |
+| `combinator` | | How criteria combine — `AND` (all must pass, default) or `OR` (any). See [Achievement Badges](Achievement-Badges.md) |
+
+```yaml
+service: taskmate.add_badge
+data:
+ name: "Super Reader"
+ description: "Complete 50 chores and maintain a 7-day streak"
+ icon: mdi:book-open-variant
+ tier: gold
+ point_bonus: 25
+ criteria:
+ - { metric: total_chores, operator: ">=", value: 50 }
+ - { metric: current_streak, operator: ">=", value: 7 }
+```
+
+### `taskmate.update_badge`
+Update an existing badge. Only supplied fields are changed. Built-in badges allow editing `point_bonus`, `tier`, `assigned_to`, `notify_on_earn`, and `enabled` — criteria, name, description, and icon are frozen.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `badge_id` | ✅ | ID of the badge to update |
+| `name` | | New name (custom only) |
+| `description` | | New description (custom only) |
+| `icon` | | New icon (custom only) |
+| `tier` | | New tier |
+| `point_bonus` | | New point bonus |
+| `criteria` | | New criteria list (custom only) |
+| `assigned_to` | | New child ID list |
+| `notify_on_earn` | | New notification setting |
+| `combinator` | | How criteria combine — `AND` (all must pass, default) or `OR` (any). See [Achievement Badges](Achievement-Badges.md) |
+
+### `taskmate.remove_badge`
+Delete a custom badge. Built-in badges cannot be removed — disable them via `update_badge` instead.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `badge_id` | ✅ | ID of the badge to remove |
+
+### `taskmate.award_badge_manually`
+Manually award a badge to a child, bypassing criteria evaluation. Credits point bonus and fires notification if `notify_on_earn` is true.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `badge_id` | ✅ | ID of the badge to award |
+| `child_id` | ✅ | ID of the child |
+
+### `taskmate.revoke_badge`
+Revoke a previously awarded badge. Automatically reverses any point bonus that was credited.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `awarded_badge_id` | ✅ | ID of the awarded badge record (from the admin panel's Award History tab or the badge sensor's `earned` array) |
+
+### `taskmate.rebuild_badges`
+Re-evaluate all badges across all children silently. Awards any newly-qualifying badges without notifications or point bonuses. No parameters.
+
+See [Achievement Badges](Achievement-Badges.md) for full details.
+
+## Bounty services (v6.0.0)
+
+One-off jobs on the [Bounty Board](Bounty-Board.md). Posting, editing and removing are parent actions; claiming, giving back and completing are done by the child (or a parent on their behalf). A finished bounty goes through the normal approval queue, so approve or reject it with `approve_chore` / `reject_chore` using its completion ID.
+
+### `taskmate.post_bounty`
+Post a job to the board for a fixed number of points.
+
+| Field | Required | Default | Description |
+| --- | --- | --- | --- |
+| `title` | ✅ | — | What the job is, e.g. "Wash the car" (up to 120 characters) |
+| `points` | ✅ | — | Points paid when a parent approves the finished job (1–100000) |
+| `description` | | — | Extra detail for the children (up to 500 characters) |
+| `icon` | | — | MDI icon shown on the board |
+| `expires_at` | | — | Date and time the bounty leaves the board if nobody has claimed it. Leave empty for no expiry |
+| `eligible_child_ids` | | all | IDs of the children who may claim it. Empty = every child |
+| `claim_hours` | | `2` | How long a claim lasts (1–48 hours) before the bounty goes back on the board |
+| `require_photo` | | `false` | The child must attach a photo when marking it done |
+| `notify_children` | | `true` | Send the **Bounty posted** notification to the eligible children (the notification type must also be switched on) |
+
+```yaml
+service: taskmate.post_bounty
+data:
+ title: Wash the car
+ points: 50
+ claim_hours: 3
+ require_photo: true
+```
+
+### `taskmate.update_bounty`
+Edit a bounty. Takes `bounty_id` plus any of the `post_bounty` fields. Once a bounty has been claimed, only its `points` and `expires_at` can change.
+
+### `taskmate.remove_bounty`
+Take a bounty off the board.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `bounty_id` | ✅ | ID of the bounty |
+
+Not allowed while a finished job is waiting for approval — approve or reject it first.
+
+### `taskmate.claim_bounty`
+Claim a bounty for a child, locking it to them for its claim period.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `bounty_id` | ✅ | ID of the bounty |
+| `child_id` | ✅ | ID of the child claiming it |
+
+A child can hold **one** claim at a time, and only bounties they are eligible for.
+
+### `taskmate.give_back_bounty`
+Hand a claimed bounty back to the board so another child can take it. Same fields as `claim_bounty`.
+
+### `taskmate.complete_bounty`
+Mark a claimed bounty as done. It goes to the approval queue like a chore.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `bounty_id` | ✅ | ID of the claimed bounty |
+| `child_id` | ✅ | ID of the child who claimed it |
+| `photo_url` | | Photo of the finished job — required when the bounty asks for one |
+
+Rejecting a finished bounty gives it back to the same child with a fresh claim lock, so they can put it right.
+
+## Wishlist services (v6.0.0)
+
+Services behind the [Wishlist](Wishlist.md). A child adds, saves towards and redeems their own wishes; approving, declining, pledging and removing are parent actions.
+
+### `taskmate.add_wish`
+A child adds something they want. It waits for a parent to approve it.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child making the wish |
+| `name` | ✅ | What the child wants |
+| `target` | ✅ | Suggested points it costs (1–100000). The parent can change it when approving |
+| `link` | | A web address (http or https) for the thing |
+| `photo_url` | | A picture just uploaded through TaskMate's photo upload |
+
+A child can have up to **5** wishes on the go at once.
+
+### `taskmate.withdraw_wish`
+A child takes back a wish that is still waiting for approval, or clears one that was declined.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `wish_id` | ✅ | ID of the wish |
+| `child_id` | ✅ | ID of the child whose wish it is |
+
+### `taskmate.move_points_to_wish`
+Move points from the child's spendable balance into one of their approved wishes. The points are reserved but still belong to the child.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `wish_id` | ✅ | ID of the wish |
+| `child_id` | ✅ | ID of the child whose wish it is |
+| `points` | ✅ | How many points to move. Capped at the child's balance and at what the wish still needs |
+
+### `taskmate.take_points_from_wish`
+Give some of the child's own saved points back to their balance. Same fields as `move_points_to_wish`. Capped at what the child saved; pledged points never come out.
+
+### `taskmate.request_wish_redeem`
+Ask to redeem a fully funded wish. It becomes a normal reward claim waiting for a parent's approval (approve or reject it with `approve_reward` / `reject_reward`).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `wish_id` | ✅ | ID of the wish |
+| `child_id` | ✅ | ID of the child whose wish it is |
+
+### `taskmate.approve_wish`
+Turn a waiting wish into a savings goal.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `wish_id` | ✅ | ID of the wish |
+| `target` | | Points the wish costs. Leave empty to keep the child's suggestion |
+
+### `taskmate.decline_wish`
+Say no to a wish. Any saved points go back to the child and pledges are cancelled.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `wish_id` | ✅ | ID of the wish |
+| `reason` | | A reason shown to the child |
+
+### `taskmate.pledge_to_wish`
+Record points a relative chips in towards a child's wish. Pledges never touch anyone's balance; they show as a separate stripe on the wish's progress bar.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `wish_id` | ✅ | ID of the wish |
+| `name` | ✅ | Who the pledge is from, e.g. "Grandma" |
+| `points` | ✅ | How many points to pledge. Capped at what the wish still needs |
+| `message` | | A message for the child |
+
+```yaml
+service: taskmate.pledge_to_wish
+data:
+ wish_id: 3c9e2f71a0b84d55
+ name: Grandma
+ points: 60
+ message: Happy saving!
+```
+
+### `taskmate.remove_wish_pledge`
+Undo a pledge. Allowed until the wish is redeemed.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `wish_id` | ✅ | ID of the wish |
+| `pledge_id` | ✅ | ID of the pledge |
+
+### `taskmate.remove_wish`
+Delete a wish. Saved points go back to the child and pledges are cancelled.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `wish_id` | ✅ | ID of the wish |
+
+## Inspection services (v6.0.0)
+
+Parent actions for [Surprise Inspections](Surprise-Inspections.md).
+
+### `taskmate.start_inspection`
+Flag a chore approved in the last 24 hours for a spot check.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `completion_id` | ✅ | ID of the approved chore completion |
+| `bonus` | | Points paid if it passes (0–10000). Defaults to the Settings value |
+| `window` | | How long you have to check it: `1h`, `2h`, `4h` or `bed` (until bedtime). Defaults to the Settings value |
+| `tell_child` | | Show "Inspection coming" on the child's card now. Turn off for a secret check. Defaults to the Settings value |
+
+An inspection nobody passes or fails before its window ends closes quietly, with no bonus.
+
+### `taskmate.pass_inspection`
+The chore passed. Pays the bonus as a normal points entry and plays a celebration on the child's card.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `inspection_id` | ✅ | ID of the open inspection |
+| `bonus` | | Points to pay. Defaults to the bonus set when the inspection started |
+| `note` | | A note shown to the child |
+
+### `taskmate.fail_inspection`
+The chore didn't pass. No points are taken away.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `inspection_id` | ✅ | ID of the open inspection |
+| `redo` | | Put the chore back on the child's list as not done for today. Defaults to the Settings value. The redo pays nothing extra; the original points stand |
+| `note` | | A note shown to the child (what needs fixing) |
+
+### `taskmate.cancel_inspection`
+Call off an open inspection, as if it never started.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `inspection_id` | ✅ | ID of the open inspection |
+
+## Family services (v7.0.0)
+
+Services for the v7.0.0 family features. The ones a child can use for themselves (`request_help`, `log_mood`, `set_weekly_goal`, `buy_raffle_tickets`, `adopt_pet`) go through the same linked-child check as `complete_chore`, so a child's account can only act for that child. `answer_help`, `set_sick_day` and `draw_raffle` are parent actions (an HA admin or a [TaskMate parent](Parent-Access.md); automations are allowed).
+
+### `taskmate.request_help`
+A child says they are stuck on a chore. Sends the parents a push; nothing is completed or skipped. See [Help Requests](Help-Requests.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | The child asking for help |
+| `chore_id` | ✅ | The chore they are stuck on |
+| `message` | | Optional words from the child, e.g. "I can't reach the shelf" (up to 120 characters) |
+
+```yaml
+service: taskmate.request_help
+data:
+ child_id: ef19c56175c14bd9
+ chore_id: 8a3b2c1d4e5f6789
+ message: "I can't reach the shelf"
+```
+
+A request stays open for two hours, or until a parent answers it. Asking again about the same chore within ten minutes is refused ("Help is already on its way").
+
+### `taskmate.answer_help`
+Mark a help request as answered, so the child's card stops saying help is on its way.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `request_id` | ✅ | The help request to close. It is in the `request_id` of the `taskmate_help_requested` event, and on the admin panel's Today page |
+
+```yaml
+service: taskmate.answer_help
+data:
+ request_id: 3c9e1a7b5d2f4e60
+```
+
+### `taskmate.log_mood`
+A child says how their day went. One per day; logging again replaces it. See [Mood Check-In](Mood-Check-In.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | The child |
+| `mood` | ✅ | `great`, `good`, `ok`, `sad` or `upset` |
+
+```yaml
+service: taskmate.log_mood
+data:
+ child_id: ef19c56175c14bd9
+ mood: good
+```
+
+A `sad` or `upset` day can send the parents a gentle push (the `mood_low` notification, off by default). Moods are kept for 90 days.
+
+### `taskmate.set_sick_day`
+Give a child a sick day: their chores are hidden, their streak is frozen and no mandatory chore is missed. See [Sick Days](Sick-Days.md).
+
+| Field | Required | Default | Description |
+| --- | --- | --- | --- |
+| `child_id` | ✅ | — | The child who is unwell |
+| `date` | | today | The day, from a week ago to a month ahead |
+| `sick` | | `true` | Set to `false` to take the sick day back |
+
+```yaml
+service: taskmate.set_sick_day
+data:
+ child_id: ef19c56175c14bd9
+ sick: true
+```
+
+### `taskmate.set_weekly_goal`
+Set a child's own weekly points goal. Reaching it pays the family's weekly goal bonus once a week. See [Weekly Goals](Weekly-Goals.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | The child |
+| `target` | ✅ | Points to earn this week (0–100000). `0` clears the goal |
+
+```yaml
+service: taskmate.set_weekly_goal
+data:
+ child_id: ef19c56175c14bd9
+ target: 120
+```
+
+Refused while **Weekly goals** is switched off in Settings. The goal carries over from week to week until it is changed.
+
+### `taskmate.buy_raffle_tickets`
+A child spends points on tickets for a raffle. Each ticket is one chance in the draw. See [Raffles](Raffles.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `raffle_id` | ✅ | The raffle. Find it in the `raffles` attribute of [`sensor.taskmate_rewards`](Sensor-Reference.md) |
+| `child_id` | ✅ | The child buying |
+| `tickets` | ✅ | How many tickets to buy (1–100) |
+
+```yaml
+service: taskmate.buy_raffle_tickets
+data:
+ raffle_id: 5b7d9f1e3a2c4b68
+ child_id: ef19c56175c14bd9
+ tickets: 3
+```
+
+Refused when the raffle has closed, isn't open to that child, the child can't afford the tickets, or the purchase would take them past the raffle's ticket cap. Raffles themselves are set up, edited and called off from the admin panel's **Raffles** tab; calling one off refunds every ticket.
+
+### `taskmate.draw_raffle`
+Draw a raffle's winner now instead of waiting for its draw time.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `raffle_id` | ✅ | The raffle to draw |
+
+```yaml
+service: taskmate.draw_raffle
+data:
+ raffle_id: 5b7d9f1e3a2c4b68
+```
+
+The winner is picked at random, weighted by tickets. A raffle nobody entered closes with no winner.
+
+### `taskmate.adopt_pet`
+A child adopts (or renames) their virtual pet. It grows with every chore they finish from now on. See [Virtual Pets](Virtual-Pets.md).
+
+| Field | Required | Default | Description |
+| --- | --- | --- | --- |
+| `child_id` | ✅ | — | The child |
+| `species` | ✅ | — | `dragon`, `cat`, `dog`, `bunny`, `dino` or `unicorn` |
+| `name` | ✅ | — | The pet's name (up to 24 characters) |
+| `hatch_egg` | | `false` | Hatch the egg the grown-up pet laid into a new pet. The old pet joins the pet family |
+
+```yaml
+service: taskmate.adopt_pet
+data:
+ child_id: ef19c56175c14bd9
+ species: dragon
+ name: Sparky
+```
+
+Refused while pets are switched off in Settings. Calling it again for a child who already has a pet renames it (or changes its species) and keeps its growth. `hatch_egg: true` is refused until the pet has laid an egg.
+
+## Miscellaneous
+
+### `taskmate.set_chore_order`
+Set the per-child display order of chores.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+| `chore_order` | ✅ | Ordered list of chore IDs |
+
+### `taskmate.preview_sound`
+Preview a completion sound in the browser.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `sound` | ✅ | Sound identifier — `none`, `coin`, `levelup`, `fanfare`, `chime`, `powerup`, `undo`, `fart1`–`fart10`, `fart_random` |
+
+### `taskmate.choose_avatar` (v4.0.0)
+A child switches to an avatar they have unlocked. See [Avatars](Avatars.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+| `icon` | ✅ | The MDI icon of an unlocked catalogue avatar (e.g. `mdi:rocket-launch`) |
+
+```yaml
+service: taskmate.choose_avatar
+data:
+ child_id: ef19c56175c14bd9
+ icon: mdi:rocket-launch
+```
+
+When invoked as a service (child self-service) the avatar must already be unlocked for that child. Parents can assign any catalogue avatar from the [Admin Panel](Admin-Panel.md) regardless of unlock state. See [Avatars](Avatars.md).
+
+### `taskmate.test_notification` (v4.0.0)
+Send a sample notification of the given type to its enabled recipients. Ignores the master on/off toggle so routing can be verified.
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `type_id` | ✅ | Notification type ID, e.g. `pending_chore_approval`, `badge_earned`, `streak_milestone`, `level_up`, `weekly_digest`, `celebration` |
+
+```yaml
+service: taskmate.test_notification
+data:
+ type_id: streak_milestone
+```
+
+See [Notifications](Notifications.md) for the full list of notification type IDs.
+
+### `taskmate.read_aloud` (v5.0.0)
+Speak a child's outstanding chores to a media player. See [Read Aloud](Read-Aloud.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+| `media_player` | | Media player to speak on. Falls back to the Settings default. |
+| `tts_entity` | | TTS engine to use. Falls back to Settings, then to the only one installed. |
+| `message` | | Speak this instead of the generated chore summary. |
+
+```yaml
+service: taskmate.read_aloud
+data:
+ child_id: ef19c56175c14bd9
+ media_player: media_player.kitchen
+```
+
+The wording comes from parent-editable templates in Settings, not from TaskMate's translations. See [Read Aloud](Read-Aloud.md) for the placeholders.
+
+### `taskmate.spin_roulette` (v5.0.0)
+Spin the chore roulette for a child: picks a random outstanding chore and applies a multiplier to it. See [Chore Roulette](Chore-Roulette.md).
+
+| Field | Required | Description |
+| --- | --- | --- |
+| `child_id` | ✅ | ID of the child |
+
+```yaml
+service: taskmate.spin_roulette
+data:
+ child_id: ef19c56175c14bd9
+```
+
+Roulette must be enabled in Settings. Only chores the child can actually do right now are eligible, and the daily spin allowance is enforced.
+
+## Service Side Effects
+
+Several services trigger additional actions beyond their primary purpose:
+
+### `approve_chore`
+- Uses the `points` override as the base when one is given (v5.7.0) — every multiplier below still applies on top
+- Applies the **quality rating** multiplier when a `rating` is given and [quality ratings](Quality-Ratings.md) are on (v6.0.0)
+- Applies the **birthday multiplier** on the child's birthday (v6.0.0, see [Birthday Mode](Birthday-Mode.md))
+- Applies the **difficulty multiplier** to the base points (`easy` ×0.5, `medium` ×1.0, `hard` ×2.0 by default — see [Difficulty Tiers](Difficulty-Tiers.md))
+- Applies the **weekend multiplier** if the current day is Saturday or Sunday (see [Bonus Points](Bonus-Points.md))
+- Applies **time incentives** when the chore sets `due_time` — `+early_bonus` if completed at/before it, `−late_penalty` if after
+- Checks and awards **streak milestone bonuses** if the child hits a configured milestone
+- Records the child as a **perfect week candidate** (checked Monday at midnight)
+- Updates the child's **current streak** and **best streak**
+- Advances **levels/XP** (`total_points_earned` is the XP pool) and fires a **level-up celebration** when a threshold is crossed — see [Levels and XP](Levels-and-XP.md) and [Celebrations](Celebrations.md)
+- Advances any matching **quests** and **challenges** — see [Quests](Quests.md) and [Challenges](Challenges.md)
+- May fire a **celebration** (e.g. all chores done) — see [Celebrations](Celebrations.md)
+- Creates a `PointsTransaction` audit record
+- Sends a **notification** (persistent + optional push) if a notify service is configured
+
+### `reject_chore`
+- **Decrements** the child's current streak by 1 (does not reset to 0)
+- Does not award any points
+- Stores the optional `reason` and shows it on the child's card for 24 hours (v6.0.0)
+- For a finished **bounty**, hands the bounty back to the same child with a fresh claim lock (v6.0.0)
+
+### `approve_reward`
+- For **wallet rewards**: deducts cost from the child's balance
+- For **pool rewards**: clears the child's allocation (points were already deducted at deposit time)
+- For **jackpot pool rewards**: each contributing child loses only their own deposited share
+- Decrements the reward's **quantity** by 1 (if limited stock)
+
+### `claim_reward`
+- Sends a **notification** (persistent + optional push) for pending reward claims
+- For **wallet rewards**: child's balance must cover the cost
+- For **pool rewards**: child's allocation must equal or exceed the cost
+- Blocked if the reward is **sold out** or **expired**
+
+### `apply_penalty` / `apply_bonus`
+- Creates a `PointsTransaction` record logged to the activity feed
+- Penalty applications show with a red shield icon in the Activity Card
+- Updates the child's `career_score` (`total_points_earned − total_penalties_received`)
+
+### `allocate_points_to_pool`
+- Immediately deducts points from the child's spendable balance
+- Creates a negative `PointsTransaction` for audit
+- Amount is silently capped at the lowest of: requested points, spendable balance, pool remaining capacity
+
+## Complete Service List
+
+The full set of `taskmate.*` services registered by the integration:
+
+`complete_chore`, `complete_bonus_subtask`, `complete_next_chore`, `approve_chore`, `approve_all_chores`, `reject_chore`, `undo_chore`, `leave_team_chore`, `apply_mandatory_penalty`, `postpone_mandatory_chore`, `dismiss_mandatory_chore`, `undo_transaction`, `undo_chore_approval`, `record_allowance_payout`, `test_notification`, `gift_points`, `adjust_streak_freezes`, `request_swap`, `choose_avatar`, `claim_reward`, `approve_reward`, `reject_reward`, `allocate_points_to_pool`, `add_points`, `remove_points`, `preview_sound`, `set_chore_order`, `add_penalty`, `update_penalty`, `remove_penalty`, `apply_penalty`, `add_bonus`, `update_bonus`, `remove_bonus`, `apply_bonus`, `add_chore`, `skip_chore`, `set_chore_manual_start`, `add_task_group`, `update_task_group`, `remove_task_group`, `start_timed_task`, `pause_timed_task`, `stop_timed_task`, `add_badge`, `update_badge`, `remove_badge`, `award_badge_manually`, `revoke_badge`, `rebuild_badges`, `read_aloud`, `spin_roulette`, `post_bounty`, `update_bounty`, `remove_bounty`, `claim_bounty`, `give_back_bounty`, `complete_bounty`, `add_wish`, `withdraw_wish`, `move_points_to_wish`, `take_points_from_wish`, `request_wish_redeem`, `approve_wish`, `decline_wish`, `pledge_to_wish`, `remove_wish_pledge`, `remove_wish`, `start_inspection`, `pass_inspection`, `fail_inspection`, `cancel_inspection`, `request_help`, `answer_help`, `log_mood`, `set_sick_day`, `set_weekly_goal`, `buy_raffle_tickets`, `draw_raffle`, `adopt_pet`.
+
+[Chore auctions](Chore-Auctions.md) have no services: they are run from the admin panel's **Auctions** page and the auction card. Raffles are created, edited and called off from the admin panel's **Raffles** tab; only buying tickets and drawing have services.
+
+## Related
+
+- [Sensor Attributes](Sensor-Attributes.md) — where to find IDs for automations
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — feature context for the pool service
+- [Gifting Points](Gifting-Points.md), [Chore Swaps](Chore-Swaps.md), [Avatars](Avatars.md), [Difficulty Tiers](Difficulty-Tiers.md), [Photo Proof](Photo-Proof.md) — v4.0.0 feature pages
+- [Mandatory Chores](Mandatory-Chores.md) — feature context for the mandatory-miss review services (v4.2.0)
+- [Points Economy](Points-Economy.md) — context for the undo services
+- [Allowance](Allowance.md) — feature context for the allowance payout service (v4.4.0)
+- [Read Aloud](Read-Aloud.md), [Chore Roulette](Chore-Roulette.md) — v5.0.0 feature pages
+- [Reactive Chores](Reactive-Chores.md) — `add_chore` with `expires_in_minutes` and `speed_bonus_points`
+- [Quality Ratings](Quality-Ratings.md), [Reject Reasons](Reject-Reasons.md), [Child Undo Window](Child-Undo-Window.md), [Teamwork Chores](Teamwork-Chores.md), [Streak Freezes](Streak-Freezes.md), [Watch Complications](Watch-Complications.md) — v6.0.0 changes to chore and points services
+- [Bounty Board](Bounty-Board.md), [Wishlist](Wishlist.md), [Surprise Inspections](Surprise-Inspections.md) — v6.0.0 service groups
+- [Help Requests](Help-Requests.md), [Mood Check-In](Mood-Check-In.md), [Sick Days](Sick-Days.md), [Weekly Goals](Weekly-Goals.md), [Raffles](Raffles.md), [Virtual Pets](Virtual-Pets.md), [Quantity Chores](Quantity-Chores.md) — v7.0.0 services
diff --git a/wiki/Settings.md b/wiki/Settings.md
new file mode 100644
index 00000000..081bb1b4
--- /dev/null
+++ b/wiki/Settings.md
@@ -0,0 +1,429 @@
+# Settings
+
+All TaskMate settings are configured via the **TaskMate** panel → **Settings**.
+
+
+
+---
+
+## Settings Reference
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Points Currency Name** | `Stars` | — | Display name for the points currency (Stars, Coins, Bucks, Tokens, etc.). Shown on all cards and notifications. |
+| **Points Currency Icon** | `mdi:star` | Any MDI icon | Icon shown next to point values throughout the UI. Since v6.2.0 the icon and name are used everywhere points appear, including bounties, auctions and every card, instead of a fixed star or "pts". |
+| **Weekend Points Multiplier** | `2.0` | 1.0–5.0 | Multiplier applied to chore points on Saturday and Sunday. Set `1.0` to disable. Formula: `weekend_bonus = round(base_points × (multiplier − 1.0))`. The bonus is logged as a separate transaction. |
+| **Streak Reset Mode** | `reset` | `reset` / `pause` | What happens when a child misses a day. **Reset**: streak goes back to 0. **Pause**: streak freezes and resumes on the next completion. |
+| **Streak Milestone Bonuses** | `on` | on / off | Master toggle for streak milestone point bonuses. |
+| **Streak Milestone Configuration** | `3:5, 7:10, 14:20, 30:50, 60:100, 100:200` | `days:points` CSV | Custom milestone thresholds. Each entry awards bonus points when the child's streak reaches that day count. Milestones reset when the streak resets, so they can be re-earned. |
+| **Streak needs all tasks** (`streak_requires_all_chores`) | `off` | on / off | When on, a day only extends the streak once **every** chore due that day is done. When off (default), completing any one chore keeps the streak alive. |
+| **Perfect Week Bonus** | `on` | on / off | Award bonus points when a child completes at least one chore every day Mon–Sun. Checked Monday at midnight. |
+| **Perfect Week Bonus Points** | `50` | 0–1000 | Points awarded per perfect week. |
+| **Perfect week needs all tasks** (`perfect_week_requires_all_chores`) | `off` | on / off | When on, a day counts toward a perfect week only when **every** chore due that day is done. When off (default), one completed chore is enough for the day to count. |
+| **Notification Service** | *(empty)* | Any `notify.*` service | Optional HA notify service for push notifications on pending chore approvals and reward claims. e.g. `notify.mobile_app_johns_phone`. Leave empty to use persistent notifications only. See [Notifications](Notifications.md). |
+| **Calendar projection** (`calendar_projection_days`) | `14` | 1–90 | Days ahead each chore publishes to the per-child calendar entities. Higher values give more planning visibility but create more calendar entries. See [Calendar](Calendar.md). |
+| **History Days to Keep** | `90` | 30–365 | Number of days of completion history to retain. Older records are pruned daily at 00:01. |
+
+> **Also available as entities (v4.4.0):** `weekend_multiplier`, `perfect_week_bonus`, `streak_reset_mode`, and `card_design` are additionally surfaced as Home Assistant `number`/`select` entities, so you can read and change them from automations, scripts, and the HA UI without the panel. Panel and entity stay in sync. See [Configuration Entities](Configuration-Entities.md).
+
+### Parents — no admin rights (v4.5.0)
+
+In the Settings tab, the **Parents (no admin rights)** section lists your non-admin Home Assistant users with a checkbox each. Ticking a user grants them the day-to-day TaskMate parent controls (approve/reject chores and rewards, adjust points, confirm allowance, complete-on-behalf, undo) from the cards — **without** Home Assistant admin rights, and without access to this admin panel or any configuration. Stored under `parent_user_ids`; only an admin can change it. See [Parent Access](Parent-Access.md).
+
+### Difficulty Multipliers (v4.0.0)
+
+Each chore carries a difficulty tier; the points it awards are the base points × the tier's multiplier. `medium` is the neutral baseline (×1.0) so chores created before this feature keep their exact award value. See [Difficulty Tiers](Difficulty-Tiers.md). Settings stored under keys `difficulty_multiplier_easy` / `difficulty_multiplier_medium` / `difficulty_multiplier_hard`.
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Easy multiplier** | `0.5` | 0.0–10.0 | Points multiplier applied to `easy` chores |
+| **Medium multiplier** | `1.0` | 0.0–10.0 | Baseline multiplier for `medium` chores |
+| **Hard multiplier** | `2.0` | 0.0–10.0 | Points multiplier applied to `hard` chores |
+
+### Levels & XP (v4.0.0)
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **XP per Level** (`level_xp_step`) | `100` | 1–100000 | Lifetime points needed to advance one [level](Levels-and-XP.md). `level = (total_points_earned // step) + 1`. |
+
+### Surprise / Random Bonus (v4.0.0)
+
+A daily (16:00) opt-in roll that may award each child a random bonus, fires the `taskmate_surprise_bonus` event. See [Points Economy](Points-Economy.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Surprise Bonus** (`surprise_bonus_enabled`) | `false` (off) | on / off | Master toggle for the random surprise bonus |
+| **Surprise chance** (`surprise_bonus_chance`) | `15` | 0–100 | Percent chance per child each day |
+| **Surprise min** (`surprise_bonus_min`) | `5` | 0–10000 | Minimum points awarded when it triggers |
+| **Surprise max** (`surprise_bonus_max`) | `20` | 0–10000 | Maximum points awarded when it triggers |
+
+### Points Decay (v4.0.0)
+
+Anti-hoarding: periodically decay each child's spendable points. Logs a transaction; does **not** touch career score. See [Points Economy](Points-Economy.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Points Decay** (`points_decay_enabled`) | `false` (off) | on / off | Master toggle |
+| **Decay period** (`points_decay_period`) | `monthly` | `weekly` / `monthly` | `weekly` runs Mondays, `monthly` runs on the 1st |
+| **Decay percent** (`points_decay_percent`) | `10` | 0–100 | Percent of the balance removed each period |
+
+### Savings Interest (v4.0.0)
+
+Rewards saving: periodically credit interest on each child's spendable balance. Fires `taskmate_interest_paid`. See [Points Economy](Points-Economy.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Savings Interest** (`interest_enabled`) | `false` (off) | on / off | Master toggle |
+| **Interest period** (`interest_period`) | `weekly` | `weekly` / `monthly` | `weekly` runs Mondays, `monthly` runs on the 1st |
+| **Interest percent** (`interest_percent`) | `5` | 0–100 | Percent of the balance credited each period |
+
+### Reward Spending Cap (v4.0.0)
+
+Limit how many points a child can spend on rewards per period. Enforced at reward approval. See [Points Economy](Points-Economy.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Spending Cap** (`spend_cap_enabled`) | `false` (off) | on / off | Master toggle |
+| **Cap period** (`spend_cap_period`) | `weekly` | `weekly` / `monthly` | `weekly` resets Mondays, `monthly` resets on the 1st |
+| **Cap amount** (`spend_cap_amount`) | `0` | 0–1000000 | Max points spendable per period (0 = unlimited) |
+
+### Celebrations (v4.0.0)
+
+Optional celebratory notifications for big moments (level-ups, streak milestones, perfect weeks, quest/challenge completions). The `taskmate_celebration` event always fires regardless of these settings; these control whether a **notification** is sent. See [Celebrations](Celebrations.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Celebration notifications** (`celebration_notify`) | `false` (off) | on / off | Send a notification on celebration moments |
+| **Minimum celebration tier** (`celebration_notify_min_tier`) | `2` | 1–3 | Only notify for moments at this tier or higher: 1 = small, 2 = medium, 3 = epic |
+
+### Time-of-Day Boundaries (v3.6.0+)
+
+These settings control the time windows used for morning, afternoon, evening, and night chores when publishing to HA calendar entities. Configurable via the [Admin Panel](Admin-Panel.md).
+
+| Setting | Default | Format | Description |
+|---------|---------|--------|-------------|
+| **Morning Start** | `06:00` | `HH:MM` | Start of the morning time window |
+| **Morning End** | `12:00` | `HH:MM` | End of the morning time window |
+| **Afternoon Start** | `12:00` | `HH:MM` | Start of the afternoon time window |
+| **Afternoon End** | `17:00` | `HH:MM` | End of the afternoon time window |
+| **Evening Start** | `17:00` | `HH:MM` | Start of the evening time window |
+| **Evening End** | `21:00` | `HH:MM` | End of the evening time window |
+| **Night Start** | `21:00` | `HH:MM` | Start of the night time window |
+| **Night End** | `23:59` | `HH:MM` | End of the night time window |
+
+Invalid values fall back to the defaults. `anytime` chores are published as all-day calendar events.
+
+### Custom Time-of-Day Periods (v4.0.0)
+
+
+
+v4.0.0 generalises the four fixed windows above into a fully **customisable period list** (`time_periods`). Each period has an `id`, a `label` (empty = use the built-in translated name), a `start`/`end` in `HH:MM`, and an `icon`. The built-in `morning` / `afternoon` / `evening` / `night` ids ship as the defaults shown above; you can rename them, change their windows, or add up to 24 periods total. The `anytime` category is implicit (all-day, always available) and never appears in the list. The legacy four `*_start`/`*_end` boundary keys are still mirrored on the overview sensor for backward compatibility.
+
+### Card Design (v4.2.0)
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Default card design** (`card_design`) | `classic` | `classic` / `playroom` / `console` / `cleanpro` / `accessible` / `graphite` | The style new cards use unless overridden per card. A selector offering Classic / Playroom / Console / Clean Pro / Accessible / Graphite. Every card left on *Use global default* follows this value. See [Card Design Styles](Card-Design-Styles.md). |
+
+### Allowance (v4.4.0)
+
+Convert points into a real-money allowance. When enabled, parents can record a payout (via [`record_allowance_payout`](Services.md#taskmaterecord_allowance_payout-v440) or the admin panel) that deducts points and logs a ledger entry at the fixed conversion rate. See [Allowance](Allowance.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Allowance enabled** (`allowance_enabled`) | `false` (off) | on / off | Master toggle for the allowance feature |
+| **Allowance rate** (`allowance_rate`) | `10` | 1–100000 | Points per one unit of currency. Cash `amount = points ÷ rate`, rounded to 2 dp |
+| **Allowance currency** (`allowance_currency`) | *(empty)* | up to 8 chars | Currency label recorded on each payout (e.g. `£`, `USD`) |
+
+### Family Goals (v4.4.0)
+
+A shared co-op goal: when the family's combined points reach the target, TaskMate fires `taskmate_family_goal_reached` and notifies. The achieved flag resets whenever the target or enabled toggle changes. See [Family Goals](Family-Goals.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Family goal enabled** (`family_goal_enabled`) | `false` (off) | on / off | Master toggle for the family co-op goal |
+| **Family goal name** (`family_goal_name`) | *(empty)* | up to 120 chars | Display name of the goal |
+| **Family goal target** (`family_goal_target`) | `500` | 1–10000000 | Combined points needed to reach the goal |
+| **Family goal reward** (`family_goal_reward`) | *(empty)* | up to 200 chars | Description of the reward earned when the goal is met |
+
+### Negative Balance (v4.4.0)
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Allow negative balance** (`allow_negative_balance`) | `false` (off) | on / off | When on, point removals (penalties, manual deductions) may take a child below zero. When off, balances are floored at 0. See [Points Economy](Points-Economy.md). |
+
+### Reminder Escalation (v4.4.0)
+
+How long after a [mandatory chore](Mandatory-Chores.md) is missed before reminders escalate. Set via the websocket command `taskmate/notifications/set_escalation`. See [Reminder Escalation](Reminder-Escalation.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Child reminder escalation** (`mandatory_escalation_reminder_minutes`) | `30` | 1–1440 | Minutes after a miss before the child reminder escalates |
+| **Parent alert escalation** (`mandatory_escalation_parent_minutes`) | `120` | 1–1440 | Minutes after a miss before the parent alert escalates |
+
+### Calendar Subscription (v4.4.0)
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **ICS feed token** (`ics_token`) | *(auto-generated)* | Secret token in the iCal subscription URL. Generated on first use of the calendar feed; rotate it (via `taskmate/calendar/regenerate_ics_token`) to invalidate existing subscriptions. See [Calendar](Calendar.md). |
+
+### Per-Child Quiet Hours (v4.4.0)
+
+Set per child (in the child editor), not globally. During a child's quiet-hours window, TaskMate suppresses notifications to that child. A start later than the end defines an overnight window. See [Quiet Hours](Quiet-Hours.md).
+
+| Setting | Default | Format | Description |
+|---------|---------|--------|-------------|
+| **Quiet hours start** (`quiet_hours_start`) | *(empty)* | `HH:MM` | Start of the do-not-disturb window; empty = no quiet hours |
+| **Quiet hours end** (`quiet_hours_end`) | *(empty)* | `HH:MM` | End of the do-not-disturb window |
+
+### Vacation Mode (v4.0.0)
+
+Define named **vacation periods** (`vacation_periods`) — each with `id`, `name`, `start`, and `end` (inclusive ISO dates). While today falls inside a vacation period, streaks are frozen (missed days don't break the streak) and the daily streak check is skipped. The overview sensor exposes `vacation_active`, `vacation_name`, `vacation_end`, and the full `vacation_periods` list. See [Vacation Mode](Vacation-Mode.md).
+
+---
+
+### Chore Roulette (v5.0.0)
+
+Off by default. Also needs `show_roulette: true` on the child card — it is doubly opt-in, so an existing dashboard never sprouts a new button. See [Chore Roulette](Chore-Roulette.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Roulette enabled** (`roulette_enabled`) | `false` (off) | on / off | Master toggle |
+| **Roulette multiplier** (`roulette_multiplier`) | `2.0` | 1.0–5.0 | Points multiplier on the chore that comes up. Values below 1 are clamped to 1 — spinning should never punish the child. |
+| **Daily spins** (`roulette_daily_spins`) | `1` | — | How many spins each child gets per day |
+
+### Unlock Allowlist (v5.0.0)
+
+The entities a [timed unlock reward](Timed-Unlock-Rewards.md) is permitted to turn on. An entry can be a full entity id (`switch.xbox`) or a bare domain (`switch`).
+
+**An empty allowlist permits nothing.** This gates household devices, so the safe default when unconfigured is "no".
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Unlock allowlist** (`unlock_allowlist`) | empty | Entity ids or domains a reward may unlock |
+
+### Read Aloud (v5.0.0)
+
+Wording comes from these parent-editable templates rather than TaskMate's translations — the frontend locales don't reach the backend, and a family may want phrasing that isn't one of the eight shipped languages. See [Read Aloud](Read-Aloud.md).
+
+| Setting | Default | Placeholders |
+|---------|---------|--------------|
+| **Default media player** (`read_aloud_media_player`) | empty | — |
+| **Default TTS entity** (`read_aloud_tts_entity`) | empty | — |
+| `read_aloud_template` | `{name}, you have {count} things left: {chores}.` | `{name}` `{count}` `{chores}` |
+| `read_aloud_one_template` | `{name}, you have one thing left: {chores}.` | same |
+| `read_aloud_done_template` | `{name}, you're all done. Nice one!` | same |
+| `read_aloud_joiner` | `and` | joins the last two chores |
+
+A template with a bad placeholder logs a warning and falls back to the built-in wording rather than silencing the feature.
+
+### Parent Approval Routing (v5.0.0)
+
+Who gets buzzed when an approval is waiting. See [Multi-Parent Approval Routing](Multi-Parent-Approval-Routing.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Parent routing** (`parent_routing`) | `all` | `all` / `home` / `round_robin` | `all` notifies every enabled parent; `home` only those whose presence entity says they're here; `round_robin` one parent per notification, rotating. Every fallback errs towards over-notifying. |
+
+### Streak Freezes (v6.0.0)
+
+In **Settings → History & streaks**. A token saves a child's streak on one missed day. See [Streak Freezes](Streak-Freezes.md).
+
+> **On by default.** Upgraded installs start using streak freezes straight away. To keep streaks working exactly as before, set **Max streak freezes** to `0`.
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Streak freezes (most a child can hold)** (`streak_freeze_max`) | `2` | 0–10 | The most tokens a child can hold. `0` turns streak freezes off |
+| **Earn a streak freeze every** (`streak_freeze_earn_every`) | `7` | 0–365 | Consecutive streak days per free token. `0` = never earned automatically (offer a **Streak freeze** reward instead, or grant tokens with [`adjust_streak_freezes`](Services.md#taskmateadjust_streak_freezes-v600)) |
+
+### Birthday Mode (v6.0.0)
+
+In **Settings → History & streaks**. Each child's birthday itself is set under **Children → Edit** (see [Per-child settings](#per-child-settings-v600) below). See [Birthday Mode](Birthday-Mode.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Birthday points multiplier** (`birthday_points_multiplier`) | `2.0` | 1.0–5.0 | Chore points on a child's birthday, on top of the weekend bonus. `1.0` = no birthday bonus |
+| **Birthday day off** (`birthday_chores_off`) | `off` | on / off | Hide non-mandatory chores on a child's birthday. The day never breaks their streak and never uses up a streak freeze |
+
+### Quality Ratings (v6.0.0)
+
+Rate each chore approval 1–3 stars and scale the points to match. An approval without a rating pays 100%. See [Quality Ratings](Quality-Ratings.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Quality ratings** (`quality_rating_enabled`) | `off` | on / off | Show the star picker on the approvals card, the panel approval queue and the phone approval notification |
+| **★ multiplier** (`quality_rating_multiplier_1`) | `0.75` | 0.0–5.0 | Points multiplier for a one-star rating |
+| **★★ multiplier** (`quality_rating_multiplier_2`) | `1.0` | 0.0–5.0 | Points multiplier for a two-star rating |
+| **★★★ multiplier** (`quality_rating_multiplier_3`) | `1.25` | 0.0–5.0 | Points multiplier for a three-star rating |
+
+### Child Undo Window (v6.0.0)
+
+In **Settings → Parents**. See [Child Undo Window](Child-Undo-Window.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Child undo window (seconds)** (`chore_undo_seconds`) | `0` (off) | 0–3600 | Lets a child take back their own chore: a submission waiting for approval until a parent reviews it, and an automatically approved chore for this many seconds after they tapped it. Once a parent has reviewed a chore, only a parent can undo it |
+
+### Recaps (v6.0.0)
+
+In **Settings → Recaps**. Off until a frequency is ticked. See [Recaps](Recaps.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Family default** (`recap_frequencies`) | none (off) | any mix of `weekly`, `monthly`, `every_3_months`, `every_6_months`, `every_9_months`, `yearly` | The recaps every child on *Family default* gets. None ticked turns recaps off. Every 9 months runs in blocks counted from 1 January 2026 |
+| **Per child** (`recap_child_frequencies`) | *Family default* | same list, per child | Override the family default for one child, e.g. weekly for a younger child and yearly for a teenager |
+| **Notify when ready → Child's device** (`recap_notify_children`) | `on` | on / off | Send the child a **Recap ready** notification |
+| **Notify when ready → Parents** (`recap_notify_parents`) | `on` | on / off | Send parents one grouped message |
+| **Send at** (`recap_send_time`) | `08:00` | `HH:MM` | Recaps are built at midnight; the notification waits until this time |
+| **Keep recaps for** (`recap_retention`) | `forever` | `1y` / `2y` / `forever` | Older recaps are deleted automatically |
+| **Compare with previous period** (`recap_compare`) | `on` | on / off | Adds the "compared with last time" slide |
+
+Nothing is sent while the **Recap ready** notification type is switched off on the Notifications tab. It is switched on for you the first time you turn recaps on.
+
+### Surprise Inspections (v6.0.0)
+
+In **Settings → Surprise inspections**. See [Surprise Inspections](Surprise-Inspections.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Inspections** (`inspections_enabled`) | `on` | on / off | Shows a 🔍 button on chores approved in the last 24 hours, in Today and Activity. Nothing happens until you press it |
+| **Bonus for a pass** (`inspection_bonus`) | `10` | 0–10000 | Default bonus; can be changed for each inspection |
+| **Time to check** (`inspection_window`) | `2h` | `1h` / `2h` / `4h` / `bed` | How long you have to pass or fail it. Unchecked inspections close with no bonus |
+| **Bedtime** (`inspection_bedtime`) | `20:00` | `HH:MM` | Used by "Until bedtime". Less than 30 minutes before it, the window is an hour |
+| **If it fails** (`inspection_fail_mode`) | `note` | `note` / `redo` / `ask` | Just note it, send the chore back to redo, or ask each time. No points are taken either way |
+| **Tell the child when it starts** (`inspection_tell_child`) | `on` | on / off | Shows "Inspection coming" on their card. Turn off for secret checks |
+| **Random daily pick** (`inspection_pick_enabled`) | `off` | on / off | TaskMate picks one approved chore for you to inspect; it shows up in **Needs you** |
+| **Pick time** (`inspection_pick_time`) | `17:00` | `HH:MM` | When the daily pick is rolled |
+| **Pick chance** (`inspection_pick_chance`) | `30` | 0–100 | Percent chance of a pick each day |
+| **Pick children** (`inspection_pick_children`) | all | child IDs | Only these children's chores can be picked. None ticked means every child. Never the same child two days running |
+
+### Presence-Aware Reminders (v6.0.0)
+
+On the **Notifications** tab, under the **Arrived home** type. Each child's presence entity is set under **Children → Edit**. See [Presence-Aware Reminders](Presence-Aware-Reminders.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Only after being away for** (`presence_arrival_min_away`) | `30` | 0–1440 minutes | The "You're home" message is only sent if the child was away at least this long |
+
+### Auto-Approve (v7.0.0)
+
+In **Settings → Parents (no admin rights)**, below the child undo window. See [Auto-Approve](Auto-Approve.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Auto-approve after (hours)** (`auto_approve_hours`) | `0` (off) | 0–168 | A chore still waiting for approval this many hours after the child finished it approves itself, at the points the child was promised, exactly as if a parent had tapped Approve. Open-ended chores and bounties always wait for you. Checked once a minute |
+
+### Personal Weekly Goals (v7.0.0)
+
+In **Settings → Personal weekly goals**. See [Weekly Goals](Weekly-Goals.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Let children set a weekly goal** (`weekly_goal_enabled`) | `off` | on / off | Shows the goal on the child card, where each child picks their own points target for the week |
+| **Bonus for reaching it** (`weekly_goal_bonus`) | `10` | 0–100000 | Paid once a week, the first time the child's points earned since Monday reach their goal. `0` = no bonus |
+
+### Virtual Pets (v7.0.0)
+
+In **Settings → Virtual pets**. Growth is counted from the day the pet is adopted. See [Virtual Pets](Virtual-Pets.md).
+
+| Setting | Default | Range | Description |
+|---------|---------|-------|-------------|
+| **Turn on virtual pets** (`pets_enabled`) | `off` | on / off | Master toggle. Children adopt a pet on the Pet card |
+| **Growth per chore** (`pet_xp_per_chore`) | `10` | 0–1000 | Growth added by every finished chore |
+| **Chore points count too** (`pet_points_count`) | `on` | on / off | Each point earned adds 1 growth, so bigger jobs grow the pet faster. Spending points never shrinks it |
+| **Hatches (baby)** (`pet_stage_baby`) | `30` | 1–1000000 | Growth needed to hatch |
+| **Little** (`pet_stage_kid`) | `200` | 1–1000000 | Growth needed for the next stage |
+| **Big** (`pet_stage_teen`) | `600` | 1–1000000 | Growth needed for the next stage |
+| **Fully grown** (`pet_stage_grown`) | `1500` | 1–1000000 | Growth needed to be fully grown. The four stage numbers must go up in order |
+| **Its home grows** (`pet_home_enabled`) | `on` | on / off | After fully grown, a new item for the pet's home every so often, up to 10 |
+| **New home item every** (`pet_home_every`) | `300` | 1–1000000 | Growth between home items |
+| **Turns legendary** (`pet_legendary_enabled`) | `on` | on / off | A gold, sparkling look after fully grown |
+| **Legendary at** (`pet_legendary_at`) | `3000` | 1–1000000 | Total growth for legendary. Must be above **Fully grown** |
+| **Lays an egg** (`pet_eggs_enabled`) | `on` | on / off | The child hatches the egg into a new pet; the old one joins the pet family |
+| **Egg at** (`pet_egg_at`) | `3000` | 1–1000000 | Used when legendary is off; otherwise the egg comes with legendary |
+| **Largest pet family** (`pet_family_max`) | `6` | 2–12 | Pets per child, counting the current one. No more eggs once it's full |
+| **Pet levels** (`pet_levels_enabled`) | `off` | on / off | A level badge that keeps going up after fully grown |
+| **New level every** (`pet_level_every`) | `300` | 1–1000000 | Growth between pet levels |
+
+A pet never loses a stage, home item, level or egg it has reached: raising a number, undoing a chore or turning an option off only changes what happens next. **Reset numbers to defaults** puts every number back.
+
+### Per-child settings (v6.0.0)
+
+Set under **Children → Edit** for each child, not globally.
+
+| Setting | Format | Description |
+|---------|--------|-------------|
+| **Birthday** (`birthday`) | `YYYY-MM-DD`, or `MM-DD` to leave the age off | Turns on [Birthday Mode](Birthday-Mode.md) for that day. 29 February is celebrated on 28 February in other years |
+| **Age group** (`age_group`) | `3_5` / `6_8` / `9_12` / `13_plus` | Used by the [Setup Wizard](Setup-Wizard.md) to suggest chores when no birthday is given |
+| **Presence (for reminders)** (`presence_entity`) | a `person.*` or `device_tracker.*` entity | While it isn't `home`, this child's reminders are held back. An `unavailable` tracker counts as home. See [Presence-Aware Reminders](Presence-Aware-Reminders.md) |
+| **Colour** (`color`) | `#rrggbb`, or *Automatic* | (v7.0.0) Marks this child's avatar and name in the admin panel. *Automatic* picks one from the child's place in the list |
+| **Kiosk PIN** | 4 digits | Asked for on a shared [kiosk](Kiosk-Mode.md) tablet. Stored hashed, so it can't be read back; leave blank to keep the current PIN |
+
+### Setup Wizard (v6.0.0)
+
+**Settings → Run setup wizard** opens the [Setup Wizard](Setup-Wizard.md) again at any time (it is also in the command search, **Ctrl K**). It only ever adds children, chores, rewards and dashboards; it never deletes anything.
+
+### Ready-Made Dashboards (v6.3.0)
+
+**Settings → Ready-made dashboards** creates a Kids, Parents or Wall tablet dashboard filled in with your children (also in the command search, **Ctrl K**). An existing dashboard is never overwritten. See [Ready-Made Dashboards](Ready-Made-Dashboards.md).
+
+## Where Settings Apply
+
+- **Currency name and icon** — shown on all cards, sensors, and notifications
+- **Weekend multiplier** — applied automatically when `approve_chore` runs on a Saturday or Sunday
+- **Streak settings** — checked at midnight (00:00:05) daily; milestones checked on each chore approval
+- **Perfect week** — checked Monday at midnight for the previous Mon–Sun period
+- **Notification service** — fires on every pending chore approval and pending reward claim
+- **Calendar projection** — recalculated at midnight and whenever a chore is created or edited
+- **History pruning** — runs daily at 00:01
+- **Time-of-day boundaries / periods** — affect calendar event windows and the time-category each chore falls into
+- **Difficulty multipliers** — applied to base points at chore approval
+- **Surprise bonus** — rolled per child daily at 16:00 when enabled
+- **Points decay / savings interest** — applied on the configured period boundary (Monday for weekly, the 1st for monthly)
+- **Spending cap** — checked when a reward claim is approved
+- **Celebrations** — notifications fire on level-ups, milestones, perfect weeks, and quest/challenge completions
+- **Vacation mode** — checked at midnight during the daily streak check
+- **Default card design** — the style applied to every card left on *Use global default*
+- **Allowance** — applied when a payout is recorded; converts points to cash at the fixed rate
+- **Family goal** — checked after point changes; fires when combined points reach the target
+- **Allow negative balance** — applied at every point removal
+- **Reminder escalation** — timed off each mandatory miss
+- **Quiet hours** — checked per child before each notification is delivered
+- **Calendar subscription token** — used to authenticate the iCal feed URL
+- **Streak freezes** — earned as the streak grows; spent in the midnight streak check on a missed day
+- **Birthday mode** — applied on the child's birthday, from midnight
+- **Quality ratings** — applied when a rated chore is approved
+- **Child undo window** — checked when a child taps a done chore to undo it
+- **Recaps** — built just after midnight at the end of each period; announced at the send time
+- **Surprise inspections** — the random pick rolls daily at the pick time; a parent reminder goes out 30 minutes before an undecided inspection closes
+- **Presence** — checked before each reminder, and when the child's tracker changes to `home`
+- **Auto-approve** — checked once a minute against every chore waiting for approval
+- **Weekly goals** — checked once a minute; the bonus is paid at most once per child per week (weeks start Monday)
+- **Virtual pets** — growth is worked out from the child's chores and points since adoption; new stages are announced within a minute
+
+---
+
+## Related
+
+- [Bonus Points](Bonus-Points.md) — detailed explanation of weekend multiplier, streaks, and perfect week
+- [Difficulty Tiers](Difficulty-Tiers.md) — difficulty multipliers
+- [Points Economy](Points-Economy.md) — surprise bonus, points decay, savings interest, and the spending cap
+- [Levels and XP](Levels-and-XP.md) — the XP-per-level setting
+- [Celebrations](Celebrations.md) — celebration notification tiers
+- [Vacation Mode](Vacation-Mode.md) — vacation periods and streak freezing
+- [Card Design Styles](Card-Design-Styles.md) — the global **Default card design** selector and per-card overrides
+- [Allowance](Allowance.md) — converting points into a real-money allowance
+- [Family Goals](Family-Goals.md) — the shared co-op goal
+- [Reminder Escalation](Reminder-Escalation.md) — mandatory-miss reminder escalation timings
+- [Quiet Hours](Quiet-Hours.md) — per-child do-not-disturb windows
+- [Configuration Entities](Configuration-Entities.md) — settings surfaced as HA number/select entities
+- [Weekly Digest](Weekly-Digest.md) — the Sunday parent summary
+- [Notifications](Notifications.md) — notification setup and examples
+- [Calendar](Calendar.md) — per-child calendar entities and publishing details
+- [Chore Roulette](Chore-Roulette.md) — the roulette multiplier and daily spins
+- [Timed Unlock Rewards](Timed-Unlock-Rewards.md) — the unlock allowlist
+- [Read Aloud](Read-Aloud.md) — the spoken-summary templates
+- [Multi-Parent Approval Routing](Multi-Parent-Approval-Routing.md) — the `parent_routing` setting
+- [Streak Freezes](Streak-Freezes.md), [Birthday Mode](Birthday-Mode.md), [Quality Ratings](Quality-Ratings.md), [Child Undo Window](Child-Undo-Window.md), [Recaps](Recaps.md), [Surprise Inspections](Surprise-Inspections.md), [Presence-Aware Reminders](Presence-Aware-Reminders.md), [Kiosk Mode](Kiosk-Mode.md), [Setup Wizard](Setup-Wizard.md) — v6.0.0 settings
+- [Auto-Approve](Auto-Approve.md), [Weekly Goals](Weekly-Goals.md), [Virtual Pets](Virtual-Pets.md) — v7.0.0 settings
+- [Getting Started](Getting-Started.md) — initial currency setup
diff --git a/wiki/Setup-Wizard.md b/wiki/Setup-Wizard.md
new file mode 100644
index 00000000..b4d5d557
--- /dev/null
+++ b/wiki/Setup-Wizard.md
@@ -0,0 +1,115 @@
+# Setup Wizard
+
+The **setup wizard** gets a new family from an empty panel to a working chore chart in a few minutes. You add your children with an age or birthday, tick from chores suggested for their age, pick some starter rewards, and it creates the lot in one go, along with [ready-made dashboards](Ready-Made-Dashboards.md) for the kids, the parents or a wall tablet. You can run it again at any time to add more; it never deletes or changes anything you already have.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## Where to Find It
+
+- **First run.** It opens by itself the first time you open the TaskMate panel with no children. If you skip it, the Today page offers **Start setup** and **Add a child myself**.
+- **Settings.** **Settings → Setup wizard → Run setup wizard**, at the top of the page.
+- **Command search.** Press **Ctrl K** and type "Run setup wizard".
+- **Integration setup.** A link at the end of adding TaskMate in Home Assistant.
+
+
+
+If you close it part-way, your draft is kept in the browser and picked up next time.
+
+---
+
+## The Steps
+
+### 1. Welcome
+
+Choose what your points are called: **Points**, **Stars**, **Coins**, **Gems** or your own name. It shows on every card and can be changed later in [Settings](Settings.md).
+
+### 2. Children
+
+Add each child with a name plus one of:
+
+- a **birthday** (this also turns on [birthday mode](Birthday-Mode.md) for them),
+- **just the age**, or
+- **rather not say**, and pick an age group by hand.
+
+Choose an avatar icon and a colour, and a preview shows their card header. The colour becomes their card's header on the Kids dashboard.
+
+
+
+### 3. Chores
+
+Suggestions are grouped by age: **3–5**, **6–8**, **9–12** and **13+**, 32 in all. Each group that has a child in it opens with its first five chores ticked.
+
+- Change the points for any chore with − and +. A **Per week, roughly** panel shows what each child would earn.
+- Tap a child's face on a chore to give it to an older sibling too. A chore is never given to a child younger than its age group.
+- Prefer a themed set? The six built-in [template packs](Template-Packs.md) (Morning routine, Evening routine, Kitchen helper and so on) are offered alongside.
+- A pack chore with the same name as a ticked suggestion, or as a chore you already have, is only added once.
+
+### 4. Rewards
+
+Starter rewards in three tiers: **Small treats**, **Worth saving for** and **Big goals**. Each shows roughly how often it could be earned with the chores you picked. Adjust the costs, or add your own. Costs are fixed.
+
+### 5. Dashboards
+
+> **New in v6.3.0.** Replaces the old "Create a Family chores dashboard" switch.
+
+Pick any, all or none of the three [ready-made dashboards](Ready-Made-Dashboards.md): **Kids** (ticked by default), **Parents** and **Wall tablet**. Each ticked one shows its options: the Kids layout and **Hide parent buttons**, **Admins only** for Parents, and the chore board tab for the wall tablet. An address that's already in use is never overwritten.
+
+
+
+You can make more at any time from **Settings → Ready-made dashboards**.
+
+### 6. Review
+
+A summary per child and the dashboards you picked, plus two choices:
+
+| Choice | Default | What it does |
+|--------|---------|--------------|
+| **Chores that need a parent's OK** | Big jobs (4+) | None, big jobs worth 4 points or more, or all |
+| **Tell me when something needs approving** | on | Switches on the approval notifications if they're off. Never switches anything off |
+
+
+
+### 7. Done
+
+**Add everything** on the review step creates it all in one go, and the Done step confirms what was added. Each dashboard is listed with an **Open** button, and any that already existed are noted as left alone. Everything is checked before anything is written, so a mistake leaves nothing half-created.
+
+---
+
+## Just the Dashboards
+
+Already set up and only after the dashboards? Run the wizard, untick any chores and rewards it suggests, and tick the dashboards you want. The Review step says "Nothing new for the family this time: just the dashboards you picked", and nothing else in TaskMate is changed.
+
+A draft saved by an older version carries over: its "Family chores" switch becomes the Kids dashboard.
+
+---
+
+## Running It on an Existing Family
+
+When you already have children, the wizard asks before opening and works in **add-only** mode:
+
+- Your existing children show as **Already set up**. You can only fill in a missing age group for them.
+- Chores and rewards with a name you already have show as **Already have** and are skipped.
+- Nothing is renamed, changed or deleted.
+
+---
+
+## New Chore Ideas as Children Grow
+
+When a birthday moves a child into the next age group, the Today page shows a one-time nudge: "Vaiha is 9 now. See new chore ideas for their age?" Either button records the new age group, so it won't come back. Suggestions never move up a group by themselves.
+
+A child's age group can also be set by hand under **Children → Edit → Age group**. It only decides which chores the wizard suggests; it changes nothing else.
+
+---
+
+## Related
+
+- [Ready-Made Dashboards](Ready-Made-Dashboards.md) — the dashboard presets, also in Settings
+- [Getting Started](Getting-Started.md) — setting TaskMate up by hand
+- [Template Packs](Template-Packs.md) — the built-in and shareable chore packs
+- [Children](Children.md) — editing children, birthdays and age groups
+- [Birthday Mode](Birthday-Mode.md) — what a birthday turns on
+- [Admin Panel](Admin-Panel.md) — the Today page and command search
diff --git a/wiki/Sick-Days.md b/wiki/Sick-Days.md
new file mode 100644
index 00000000..d5ffbdee
--- /dev/null
+++ b/wiki/Sick-Days.md
@@ -0,0 +1,75 @@
+# Sick Days
+
+When a child is ill, one tap gives them a sick day. Their chores disappear for the day, their streak is frozen so it survives, and no mandatory chore counts as missed. Their card shows a gentle "rest up" banner instead of a to-do list. It works like a one-child, one-day [vacation](Vacation-Mode.md), with nothing to set up beforehand.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Giving a Sick Day
+
+**TaskMate panel → Today**: each child's card has a sick-day button (the 🤒 face, next to the points button). Tap it to give that child a sick day today; tap it again to take it back.
+
+
+
+While a child is on a sick day their card on the Today page shows a **Sick day** pill and the button stays highlighted.
+
+To mark a different day (from a week ago to a month ahead), use the `set_sick_day` service, for example from an automation or a dashboard button:
+
+```yaml
+action: taskmate.set_sick_day
+data:
+ child_id: 8e16ad66b23f404e
+ date: "2026-11-03"
+```
+
+---
+
+## What a Sick Day Does
+
+For that child, on that day:
+
+| | |
+|---|---|
+| **Chores** | Hidden. Their card shows **Sick day — Rest up and get better. No chores today.** |
+| **Streak** | Frozen. The day never counts as missed, and a sick day bridges a gap just as a vacation does, so a streak survives it |
+| **Mandatory chores** | No missed-mandatory review items are raised |
+| **Virtual pet** | Doesn't get sleepy; it stays content (see [Virtual Pets](Virtual-Pets.md#moods)) |
+| **Logging past jobs** | A job can't be [logged for that day](Logging-Past-Jobs.md) afterwards: "Tuesday was Vaiha's sick day, so no jobs were due." |
+
+Other children aren't affected.
+
+Sick days are kept for 120 days, then dropped.
+
+---
+
+## Taking It Back
+
+Tap the sick-day button on the Today page again, or call the service with `sick: false`. The child's chores come back straight away.
+
+---
+
+## Event
+
+Setting or clearing a sick day fires `taskmate_sick_day` with `child_id`, `child_name`, `date` and `sick` (`true` or `false`). It shows as **Sick day** on the child's [event entity](Event-Entities.md), handy for, say, turning off the morning chore announcement.
+
+---
+
+## Service
+
+| Service | Fields | Description |
+|---------|--------|-------------|
+| `taskmate.set_sick_day` | `child_id`, `date` (optional, default today; a week ago to a month ahead), `sick` (optional, default `true`; `false` takes it back) | Give a child a sick day, or take it back |
+
+Each child's entry in `sensor.taskmate_overview`'s `children` attribute carries `sick_today: true` on a sick day.
+
+---
+
+## Related
+
+- [Vacation Mode](Vacation-Mode.md) — time off for the whole family, or by date range
+- [Streak Freezes](Streak-Freezes.md) — tokens that save a streak on a missed day
+- [Mandatory Chores](Mandatory-Chores.md) — what a missed mandatory chore normally does
+- [Mood Check-In](Mood-Check-In.md)
diff --git a/wiki/Sticker-Chart-Card.md b/wiki/Sticker-Chart-Card.md
new file mode 100644
index 00000000..1d1ba266
--- /dev/null
+++ b/wiki/Sticker-Chart-Card.md
@@ -0,0 +1,122 @@
+# Sticker Chart Card
+
+The fridge-door sticker chart, on a dashboard. Each of today's jobs is a big sticker for your child to tap, every point they've saved shows as a sticker of its own, and a row of blocks fills up towards the reward they're saving for. It's made for young children and a wall tablet: there's almost nothing to read, and every job is one tap.
+
+
+
+> **New in v6.4.0** — contributed by @cad861
+
+---
+
+## Adding the Card
+
+**Edit dashboard → + Add Card → TaskMate Sticker Chart**
+
+```yaml
+type: custom:taskmate-sticker-chart-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a # optional — leave out for every child, side by side
+```
+
+The card is meant to fill a view, so it works best in a **Panel** view or a wide section. Without `child_id` you get one column per child, side by side.
+
+---
+
+## What the Card Shows
+
+**At the top**
+
+- **Today: 3 / 7 jobs done** — how far through the day they are
+- **A sticker for every point** towards the goal (the row stops growing once the goal is reached). The stickers cycle through stars, unicorns, rockets, dinosaurs and more, so a long row never looks the same. Past 40 stickers the row is summarised with a count such as `+10`
+- **Their face** — the child's [photo](Children.md#child-photos), or their avatar icon
+- **Blocks towards the goal** — "18 / 30 Points to the reward", with a block lighting up for each point. For big rewards each block stands for several points, and a note under the row says how many
+
+**The jobs**
+
+One tile per job due today, across every time of day at once:
+
+| Tile | Meaning |
+|------|---------|
+| Grey, dashed | Still to do |
+| Bright colour, tilted | Done |
+| Amber, with ⏳ | Done, waiting for a grown-up to approve |
+| Amber stripe filling up | Started — a chore that can be done several times a day, part-way through |
+| 📷 in the corner | Needs a photo, so it has to be finished on the [child card](Dashboard-Cards.md#child-card) |
+
+Each tile picks its picture from the chore: the chore's [picture](Chores.md#chore-pictures-v510) if it has one, an emoji at the start of its name (`🦷 Brush teeth`) if not, and otherwise a sticker matched from the name — teeth, bed, shoes, homework, the dog and so on.
+
+**At the bottom**
+
+The reward they're saving for, and a **Claim** button once they have enough. Claiming needs two taps, so a passing hand can't spend their points, and the claim goes to you for approval like any other.
+
+---
+
+## Ticking Jobs Off
+
+- **Tap** a tile to mark the job done. It goes through TaskMate exactly as the child card does: the chore's button entity is pressed if it has one, so your automations still fire. The chore's [completion sound](Completion-Sounds.md) plays and a celebration pops up, with a bigger one when the last job of the day is done.
+- **Press and hold** a done tile to take it back. Only a parent can undo a job, so on a child's login the card says so instead.
+- Jobs that need [approval](Approvals-Card.md) show as waiting until you approve them.
+
+Some jobs can't be finished from a tile and are left off, or sent to the child card:
+
+- [Photo proof](Photo-Proof.md) jobs show 📷 and say to finish them on the child card
+- [Open-ended chores](Open-Ended-Chores.md) aren't shown — the child needs to describe what they did
+- Rotation chores show only for the child whose turn it is
+
+---
+
+## Counting Towards the Week Instead
+
+Set `goal: week` (**What the stickers count towards → This week's jobs** in the editor) and the blocks count the week rather than the reward. The stickers and blocks then show the points earned since Monday, out of every point the week's jobs could give, and a full row reads **PERFECT WEEK!** The reward and the Claim button stay as they are.
+
+---
+
+## Options
+
+| Option | Default | Description |
+|--------|---------|-------------|
+| `entity` | — | **Required.** `sensor.taskmate_overview` |
+| `child_id` | all children | One child's chart. Leave out for every child, side by side |
+| `reward_id` | automatic | The reward to save for. Automatic aims at the cheapest reward the child can't afford yet |
+| `goal` | `reward` | `reward` or `week` — what the stickers and blocks count towards |
+| `title` | "{name}'s Sticker Chart" | Heading above each chart |
+| `columns` | `4` | Job tiles per row, 2–6 |
+| `show_today` | `true` | Show the "Today: x / y jobs done" line |
+| `show_claim` | `true` | Show the Claim button |
+| `allow_undo` | `true` | Press and hold a sticker to take it back (parents only) |
+| `sound` | `true` | Play the chore's completion sound |
+| `show_adults` | `false` | Include [adult profiles](Adult-Profiles.md) when no `child_id` is set. The editor shows this switch once your family has an adult |
+| `card_design` | global | See [Card Design Styles](Card-Design-Styles.md) |
+
+In YAML only:
+
+| Option | Default | Description |
+|--------|---------|-------------|
+| `celebrate` | `true` | `false` turns off the pop-up and confetti |
+| `default_sound` | `coin` | Sound for chores that don't set their own |
+| `undo_sound` | `undo` | Sound when a sticker is taken back |
+
+```yaml
+type: custom:taskmate-sticker-chart-card
+entity: sensor.taskmate_overview
+child_id: a8c8376a
+reward_id: 9f2c41d0
+goal: week
+columns: 5
+```
+
+---
+
+## On a Shared Tablet
+
+The card ticks jobs as whoever is signed in. If a tablet's account isn't allowed to act for a child, the card says so and explains the fix: link the child to that account, or add the account as a parent. See [Parent Access](Parent-Access.md).
+
+---
+
+## Related
+
+- [Logging Past Jobs](Logging-Past-Jobs.md) — the same sticker chart, for a day that has gone
+- [Dashboard Cards](Dashboard-Cards.md) — every TaskMate card
+- [Rewards](Rewards.md) — what the stickers save towards
+- [Kiosk Mode](Kiosk-Mode.md) — another card made for a wall tablet
+- [Pre-Reader Mode](Pre-Reader-Mode.md) — the child card for children who can't read yet
diff --git a/wiki/Streak-Freezes.md b/wiki/Streak-Freezes.md
new file mode 100644
index 00000000..c167a36d
--- /dev/null
+++ b/wiki/Streak-Freezes.md
@@ -0,0 +1,111 @@
+# Streak Freezes
+
+A long streak is precious, and one forgotten day shouldn't wipe out weeks of effort. A **streak freeze** is a token a child holds in reserve: when they miss a day, a token is used up instead of the streak breaking.
+
+
+
+> **New in v6.0.0**. Streak freezes are **switched on by default**. See [Turning It Off](#turning-it-off).
+
+---
+
+## How It Works
+
+```
+Child misses a day → midnight streak check → a token is used → the streak carries on
+```
+
+Each night TaskMate checks every child's streak. For each missed day it uses up one token, in date order, and the streak survives. The next completion carries the streak on across the gap as if nothing happened.
+
+If the tokens run out partway through a longer gap, the streak breaks (or pauses, depending on your streak mode) exactly as it did before streak freezes existed.
+
+---
+
+## Getting Tokens
+
+There are three ways a child can get a token.
+
+### Earning them
+
+A child earns **one token every 7 streak days** by default: at 7 days, 14 days, 21 days, and so on, up to the most they can hold.
+
+If the completion that earned a token is undone, the token is taken back, so tapping undo and redo can't farm tokens.
+
+### Buying them
+
+Create a reward and switch on **Streak freeze** in the reward editor. Approving a claim gives the child one token. The reward shows a *Streak freeze* pill in the rewards list.
+
+- The cost is always fixed.
+- A claim is refused if the child already holds the most they're allowed. Claims still waiting for approval count toward that limit.
+- A streak-freeze reward can't be a jackpot.
+
+See [Managing Rewards](Managing-Rewards.md).
+
+### Given by a parent
+
+Grant or remove tokens with the `taskmate.adjust_streak_freezes` service:
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `child_id` | Yes | The child |
+| `amount` | Yes | From `-10` to `10`, not `0`. Positive grants tokens, negative removes them. |
+
+```yaml
+action: taskmate.adjust_streak_freezes
+data:
+ child_id: a8c8376a
+ amount: 1
+```
+
+A grant never takes a child over the limit, and a removal stops at zero. Only parents and admins can use it.
+
+---
+
+## Settings
+
+**TaskMate panel → Settings → History & streaks**
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Streak freezes (most a child can hold)** | `2` | The most tokens a child can hold, up to `10`. `0` turns streak freezes off. |
+| **Earn a streak freeze every** | `7` | Streak days per free token. `0` = never. Use this if you'd rather children buy tokens with a reward. |
+
+### Turning It Off
+
+To keep streaks working exactly as they did before v6.0.0, set **Streak freezes (most a child can hold)** to `0`.
+
+---
+
+## Days That Never Use a Token
+
+Some days are already forgiven, so they never cost a token:
+
+- **[Vacation](Vacation-Mode.md)** days
+- Days a child is **away** (the global vacation calendar, or an unavailability sensor with *pause streak* switched on)
+- A **[birthday day off](Birthday-Mode.md)**
+- A streak that's already **paused**, or a child with no streak at all
+
+---
+
+## Where Tokens Show
+
+| Where | What you see |
+|-------|--------------|
+| **Streak card** | A ❄️ count next to each child's streak, in every card design. It still shows `0` while the feature is on. |
+| **Child card** | ❄️ N in the header, once the child holds at least one token. |
+| **Activity** | An entry each time a token is earned, used, given, removed or taken back. These entries carry no points and can't be undone. |
+
+---
+
+## Notification and Event
+
+- The **Streak freeze used** notification type tells you when a token saves a child's streak. It's off by default. Turn it on under **TaskMate panel → Notifications**.
+- The `taskmate_streak_freeze_used` event fires each time a token is used, for your own automations.
+
+---
+
+## Related
+
+- [Vacation Mode](Vacation-Mode.md) — pausing chores and streaks for a trip
+- [Managing Rewards](Managing-Rewards.md) — creating a Streak freeze reward
+- [Birthday Mode](Birthday-Mode.md) — a birthday day off never uses a token
+- [Services](Services.md) — full service reference
diff --git a/wiki/Surprise-Inspections.md b/wiki/Surprise-Inspections.md
new file mode 100644
index 00000000..2019d395
--- /dev/null
+++ b/wiki/Surprise-Inspections.md
@@ -0,0 +1,99 @@
+# Surprise Inspections
+
+"I tidied my room!" — but did they? A **surprise inspection** lets you spot-check a chore you've already approved. If it still looks good when you check, the child earns a bonus. If it doesn't, you can just note it, or send it back to be redone. No points are ever taken away, so inspections reward keeping things tidy rather than punishing a slip.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## How It Works
+
+1. **Flag a chore.** Any chore approved (or auto-approved) in the last 24 hours shows a 🔍 magnifier in **Recent activity** on the Today page and in Activity. Tap it.
+2. **Set it up.** Choose how long you have to check it (1 hour, 2 hours, 4 hours or until bedtime), the bonus (10 points by default, editable), and whether to tell the child now. Turn **Tell … now** off for a secret check.
+3. **Check it.** The open inspection sits at the top of **Needs you** on the Today page with a countdown, and **Pass**, **Fail** and cancel buttons.
+4. **Decide.** Pass pays the bonus; fail notes it or sends the chore back.
+
+Each approved chore can be inspected once.
+
+---
+
+## What the Child Sees
+
+When the child has been told, their card shows an amber **Inspection coming!** banner with the countdown and the bonus, and the chore gets a dashed border and an **Inspection** tag.
+
+
+
+| Outcome | On the child's card |
+|---------|---------------------|
+| **Passed** | A one-off celebration with your note, then a green banner and a **Passed +10** tag for the rest of the day |
+| **Failed — just noted** | A grey "Not this time. No points lost." |
+| **Failed — sent back** | The chore reappears as not done for today, with your note |
+| **Secret check** | Nothing at all until you decide |
+
+---
+
+## Passing and Failing
+
+- **Pass** pays the bonus as an ordinary points transaction ("Inspection passed: Tidy the playroom"). You can change the bonus as you pass it. Like any bonus it can be undone from the activity feed; undoing it takes the pass back and reopens the inspection if its time is still open.
+- **Fail → Just note it** records the result. The child keeps the chore's original points.
+- **Fail → Send it back to redo** puts the chore back on the child's list for today. They complete it again through the normal path (including approval, if the chore needs it), but the redo **pays nothing extra**. The original points stand.
+- **Time runs out** — if you don't decide in time, the inspection closes quietly with no bonus. You get a reminder 30 minutes before.
+- **Cancel** (✕) drops the inspection without a result.
+
+Rejecting the inspected completion itself also cancels an open inspection on it.
+
+---
+
+## Settings
+
+**TaskMate panel → Settings → Surprise inspections**
+
+
+
+| Setting | Default | Description |
+|---------|---------|-------------|
+| **Inspections** | on | Shows the magnifier on chores approved in the last 24 hours, in Today and Activity |
+| **Bonus for a pass** | `10` | The starting bonus. Can be changed for each inspection |
+| **Time to check** | 2 hours | The starting window: 1 hour, 2 hours, 4 hours or until bedtime |
+| **Bedtime** | `20:00` | Used by "Until bedtime". Less than 30 minutes before it, the window is an hour |
+| **If it fails** | Just note it | Just note it, Send it back to redo, or Ask me each time |
+| **Tell the child when it starts** | on | The starting position of the "Tell … now" switch |
+| **Random daily pick** | off | TaskMate picks one approved chore for you to inspect. It shows up in Needs you |
+| **When and how often** | `17:00`, 30% | The daily time the pick is made, and the chance it happens on any given day |
+| **Children** | all | Which children can be picked. None ticked means every child |
+
+The random pick only chooses chores approved that day, and never the same child two days running.
+
+---
+
+## Notifications
+
+| Type | Sent to | Default |
+|------|---------|---------|
+| **Inspection started** | The child (only when told) | Off |
+| **Inspection passed** | The child | Off |
+| **Inspection reminder** | Parents, 30 minutes before the window closes | **On** |
+
+---
+
+## Services and Events
+
+| Service | Description |
+|---------|-------------|
+| `taskmate.start_inspection` | Start one on a `completion_id`. Optional `bonus`, `window` (`1h`, `2h`, `4h` or `bed`) and `tell_child` |
+| `taskmate.pass_inspection` | Pass it (`inspection_id`), with an optional `bonus` override and `note` |
+| `taskmate.fail_inspection` | Fail it, with an optional `redo` (send it back) and `note` |
+| `taskmate.cancel_inspection` | Cancel it |
+
+All four are parent-only. Events: `taskmate_inspection_started`, `_passed`, `_failed`, `_expired`, `_cancelled` and `_reopened`. The activity feed and Activity card show started, didn't-pass and sent-back entries (a secret inspection only appears once it's decided).
+
+---
+
+## Related
+
+- [Bonuses](Bonuses.md) — the other ways to hand out extra points
+- [Managing Rewards](Managing-Rewards.md) — the approval queue
+- [Admin Panel](Admin-Panel.md) — the Today page and Needs you
+- [Celebrations](Celebrations.md) — the animation a pass plays on the child's card
diff --git a/wiki/Task-Groups.md b/wiki/Task-Groups.md
new file mode 100644
index 00000000..e4ed3227
--- /dev/null
+++ b/wiki/Task-Groups.md
@@ -0,0 +1,138 @@
+# Task Groups
+
+Task Groups coordinate how rotation-mode chores are assigned together. They solve the problem of related chores being randomly split across different children when you want them handled as a set.
+
+
+
+---
+
+## Why Use Task Groups?
+
+Without groups, three rotation-mode chores (Set Table, Serve Dinner, Clear Table) might be assigned to three different children on the same day. With a **sticky** group, all three go to the same child. With a **spread** group, each goes to a different child — guaranteed.
+
+---
+
+## Policies
+
+### Sticky
+
+All chores in the group are assigned to the **same child** today.
+
+- The **first chore** in the group is the **leader** — its rotation pick determines who gets the whole group
+- All other chores (followers) are forced onto the leader's assigned child, provided that child is in their assignment pool
+- If the leader's child is not in a follower's pool, the follower falls back to its own rotation pick
+
+**Use case:** Related chores that should be done by one person — setting and clearing the table, washing and drying dishes.
+
+### Spread
+
+Each chore in the group is assigned to a **different child** — no child gets two chores from the same group on the same day.
+
+- Children are distributed in order, wrapping around if there are more chores than children
+- Each chore starts from its own raw rotation pick, then walks forward to find an unused child
+
+**Use case:** Distributing a set of equivalent chores fairly — three different rooms to tidy, each assigned to a different child.
+
+---
+
+## Creating a Task Group
+
+### Via the Admin Panel
+
+1. Open the **TaskMate** panel in the HA sidebar
+2. Navigate to task group management
+3. Click **Add Task Group**
+4. Enter a name, select a policy (sticky or spread), and choose the chores to include
+5. Save
+
+### Via Services
+
+```yaml
+service: taskmate.add_task_group
+data:
+ name: "Dinner Duties"
+ policy: sticky
+ chore_ids:
+ - abc12345
+ - def67890
+ - ghi11223
+```
+
+---
+
+## Services
+
+### `taskmate.add_task_group`
+
+Create a new task group.
+
+| Field | Required | Default | Description |
+|-------|----------|---------|-------------|
+| `name` | Yes | — | Group display name |
+| `policy` | Yes | `sticky` | `sticky` or `spread` |
+| `chore_ids` | No | `[]` | Ordered list of chore IDs |
+
+### `taskmate.update_task_group`
+
+Update an existing group. Only supplied fields are changed.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `group_id` | Yes | ID of the group to update |
+| `name` | No | New name |
+| `policy` | No | New policy |
+| `chore_ids` | No | New ordered chore list |
+
+```yaml
+service: taskmate.update_task_group
+data:
+ group_id: grp_abc123
+ policy: spread
+```
+
+### `taskmate.remove_task_group`
+
+Delete a task group. The chores themselves are not deleted — they revert to independent rotation.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `group_id` | Yes | ID of the group to remove |
+
+```yaml
+service: taskmate.remove_task_group
+data:
+ group_id: grp_abc123
+```
+
+---
+
+## How Groups Interact with Assignment Modes
+
+- Groups **only apply** to chores using rotation assignment modes (`alternating`, `random`, `balanced`)
+- Chores in `everyone` mode are unaffected by groups — every child sees them regardless
+- Group policies are applied **after** the raw per-chore rotation picks are calculated at midnight
+- The order of `chore_ids` matters for sticky groups — the first chore is the leader
+
+---
+
+## Skip Behaviour
+
+- **Sticky followers** cannot be skipped individually — skip the leader and followers follow
+- **Leader skip** propagates to all followers via the daily assignment recompute
+- **Spread groups** allow individual chore skips normally
+
+---
+
+## Tips
+
+- **Keep groups small** (2–4 chores) — large groups with sticky policy can overload one child
+- **Order matters** for sticky — put the most important chore first as the leader
+- **Mix with balanced mode** — balanced + spread distributes work most evenly across children
+- **Use spread for fairness** — when all group chores are equivalent effort, spread ensures no child does two
+
+---
+
+## Related
+
+- [Chores — Assignment Modes](Chores.md#assignment-modes) — how rotation modes work
+- [Services](Services.md) — full service reference
diff --git a/wiki/Teamwork-Chores.md b/wiki/Teamwork-Chores.md
new file mode 100644
index 00000000..fcc2992c
--- /dev/null
+++ b/wiki/Teamwork-Chores.md
@@ -0,0 +1,117 @@
+# Teamwork Chores
+
+Some jobs are meant to be done together: washing the car, clearing the garden, carrying the shopping in. A **teamwork chore** only counts once a set number of children have joined it. Each child taps to join, and when the team is full, everyone gets the credit at once.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## How It Works
+
+```
+Mia taps Join (1 / 2 joined) → Leo taps Join → team full → both get a completion
+```
+
+- Each child's tap **joins** the team. A join on its own records nothing and pays nothing.
+- The tap that **fills the team** records a completion for every member together.
+- Those completions follow the chore's normal approval setting. If it needs approval, they all land in the approval queue together.
+- If a parent completes it on a child's behalf and that fills the team, it's approved straight away, as with any chore completed by a parent.
+
+---
+
+## Setting It Up
+
+**TaskMate panel → Chores → edit a chore → More options → Teamwork (optional)**
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Team size (0 = off)** | `0` | How many different children must join, from `2` to `10`. `0` makes it an ordinary chore. |
+| **Team points** | Everyone gets the full points | *Everyone gets the full points*, or *Split the points evenly (rounded down)*. |
+| **Team bonus (per child)** | `0` | Extra points for each member when the team completes it. |
+
+Teamwork chores show a **Team of N** pill in the chore list.
+
+### Points example
+
+A 20-point chore with a team of 2 and a team bonus of 5:
+
+| Team points | Each child gets |
+|-------------|-----------------|
+| Everyone gets the full points | 20 + 5 = **25** |
+| Split evenly | 10 + 5 = **15** |
+
+The child card quotes each child their own share, so the number they see is the number they'll get. Rewards are unaffected: reward costs are always fixed.
+
+---
+
+## On the Child Card
+
+A teamwork chore shows how the team is filling up, for example **1 / 2 joined**, with the avatars of the children who have joined. Once a child has joined, it also says **You're in**.
+
+| Button | What it does |
+|--------|--------------|
+| **Join** | Adds the child to today's team. |
+| **Leave** | Takes them back out, as long as the team isn't full yet. |
+
+A join that doesn't fill the team doesn't play the "done" celebration. That happens when the team completes it. This works in every card design and in pre-reader mode.
+
+On the [kiosk card](Dashboard-Cards.md), a child who has joined sees "Waiting for your team".
+
+---
+
+## Every Day Starts Fresh
+
+Joins belong to **today's** occurrence of the chore. A half-formed team resets at midnight, so nobody is left waiting from yesterday. Editing the chore never clears today's joins.
+
+---
+
+## What Can't Be a Teamwork Chore
+
+A teamwork chore has to use the normal **everyone** assignment, where every assigned child sees the chore and can join. So it can't also be:
+
+- **First-come** or any **[rotation](Task-Groups.md)** mode (alternating, random, balanced). Those give the chore to one child, so a team could never form.
+- **[Open-ended](Open-Ended-Chores.md)**
+- A **[timed task](Timed-Tasks.md)**
+
+The chore editor, the WebSocket API and the `add_chore` service all refuse these combinations.
+
+Photo proof still works: each child's join goes through the usual checks, including the photo.
+
+---
+
+## Services and Events
+
+`taskmate.add_chore` accepts `team_size`, `team_points_mode` (`each` or `split`) and `team_bonus`.
+
+A child can leave a team with `taskmate.leave_team_chore`:
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `chore_id` | Yes | The teamwork chore |
+| `child_id` | Yes | The child leaving |
+
+| Event | When |
+|-------|------|
+| `taskmate_team_chore_joined` | A child joins a team that isn't full yet |
+| `taskmate_team_chore_completed` | The team fills and completions are recorded |
+
+The usual `taskmate_chore_completed` event also fires once for each member.
+
+---
+
+## Good Candidates
+
+- **Washing the car**: two children, split the points, add a team bonus
+- **Garden clear-up**: three children, everyone gets the full points
+- **Unloading the shopping**: a quick team of two
+- **Tidying the playroom** that everyone made a mess of
+
+---
+
+## Related
+
+- [Chores](Chores.md) — creating and configuring chores
+- [Chore Scheduling](Chore-Scheduling.md) — assignment and rotation modes
+- [Family Goals](Family-Goals.md) — a shared points target for the whole family
diff --git a/wiki/Template-Packs.md b/wiki/Template-Packs.md
new file mode 100644
index 00000000..01ec3004
--- /dev/null
+++ b/wiki/Template-Packs.md
@@ -0,0 +1,45 @@
+# Template Packs
+
+Export your custom chore templates as a JSON pack, and import one somebody else made.
+
+
+
+- **Export** — `taskmate/templates/export` returns a pack: all custom templates, or a chosen subset. Built-ins are excluded, because they ship with TaskMate and exporting them would only create duplicates on the other end.
+- **Import** — `taskmate/templates/import` takes a pack object.
+
+---
+
+## Import Is Treated as Untrusted
+
+A pack is arbitrary JSON from someone else, so it is handled defensively:
+
+- **Unknown chore fields are dropped**, not carried through. A shared pack cannot set runtime state — rotation anchors, skip dates — or anything the panel wouldn't let you set by hand.
+- **Format and version are checked.** A pack from a newer TaskMate says so plainly rather than being half-imported.
+- **Sizes are capped** — 50 templates, 200 chores each. Long names are truncated rather than rejected.
+- **A clashing name is suffixed, never overwritten** — `Morning routine (2)`. An import must not silently replace something your family built.
+- **A pack that fails validation writes nothing.** There is no partial import to clean up afterwards.
+
+---
+
+## No URL Importing
+
+Packs are imported from **pasted or uploaded JSON only**. Fetching arbitrary URLs from inside your home network would make TaskMate a server-side request forgery vector — a shared "pack link" could be used to probe your LAN. You can still paste a gist's raw contents.
+
+---
+
+## Sharing a Pack
+
+1. Export your templates from the panel.
+2. Send the JSON however you like — a gist, a forum post, a message.
+3. The recipient pastes it into the import dialog.
+
+Because names are suffixed rather than overwritten, importing a pack twice gives you a duplicate to delete, never a silent replacement of your own work.
+
+---
+
+## Related
+
+- [Chores](Chores.md) — creating chores from a template
+- [Admin Panel](Admin-Panel.md) — the Templates tab
+- [Backup & Restore](Backup-and-Restore.md) — exporting your whole configuration, which is a different job
+- [Services](Services.md) — the websocket commands
diff --git a/wiki/Time-Locked-Rewards.md b/wiki/Time-Locked-Rewards.md
new file mode 100644
index 00000000..a02cf524
--- /dev/null
+++ b/wiki/Time-Locked-Rewards.md
@@ -0,0 +1,62 @@
+# Time Locked Rewards
+
+Some rewards only make sense at certain times. Film night belongs to Friday evening; an hour of screen time shouldn't be claimable at 6am on a school day. A time lock restricts *when* a reward can be claimed, without hiding it the rest of the week.
+
+Added in v5.6.0.
+
+
+
+---
+
+## How It Behaves
+
+The reward stays visible on the card the whole time. Outside its window it is shown as locked and cannot be claimed; inside it, nothing is different from any other reward.
+
+Two things are deliberately **not** blocked:
+
+- **Saving into a pool.** A child can keep putting points into a savings jar for a time-locked reward whenever they like — only the final claim waits for the window.
+- **Parent approval.** If a claim is already waiting when the window closes, a parent can still approve it. Approving is the parent's decision, not the child's, so it is not held to the child's window.
+
+---
+
+## Setting It Up
+
+Open a reward in the admin panel and find **Advanced — time lock**, then turn on **Limit when this can be claimed**.
+
+
+
+**Days** — tick the days the reward is claimable. Leave every day unticked for no day restriction.
+
+**From / Until** — a time-of-day window. Leave both blank for any time of day.
+
+The two parts are independent. Set only days, only a window, or both — whatever you configure has to pass.
+
+---
+
+## Key Points
+
+- **The end time is exclusive.** `07:00–19:00` stops at 19:00 exactly.
+- **Equal times mean no restriction.** `07:00–07:00` is treated as "any time", not as a full 24 hours, so a half-finished window never silently locks a reward forever.
+- **A start later than the end spans midnight.** `20:00–01:00` runs through the evening and into the early hours.
+- **An overnight window on a day-restricted reward only covers the part before midnight.** The day is read from the moment of the claim, so a Friday-only reward with a `20:00–01:00` window is claimable from 20:00 to 23:59 on Friday — the hour after midnight belongs to Saturday, which isn't ticked.
+- **The lock is enforced in the backend**, not just drawn on the card, so a service call or automation cannot claim around it.
+- **Turning the lock off restores normal behaviour** immediately; the day and time settings are kept in case you want it back.
+
+---
+
+## Worked Examples
+
+| Goal | Days | From | Until |
+|------|------|------|-------|
+| Friday film night | Friday | `17:00` | `22:00` |
+| Weekend lie-in treat | Saturday, Sunday | blank | blank |
+| After school only, any weekday | Mon–Fri | `15:30` | `18:00` |
+| Late-evening screen time spanning midnight | Saturday | `20:00` | `01:00` |
+
+---
+
+## See Also
+
+- [Rewards](Rewards.md) — costs, stock, expiry and the claim flow
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — saving towards a reward over time
+- [Timed Unlock Rewards](Timed-Unlock-Rewards.md) — a reward that switches a device on for a while
diff --git a/wiki/Timed-Tasks.md b/wiki/Timed-Tasks.md
new file mode 100644
index 00000000..6da63f28
--- /dev/null
+++ b/wiki/Timed-Tasks.md
@@ -0,0 +1,181 @@
+# Timed Tasks
+
+Timed Tasks let children earn points based on how long they spend on an activity rather than a simple tick-off. Ideal for reading, practising an instrument, or any chore where effort = duration.
+
+
+
+---
+
+## How It Works
+
+```
+Child starts timer → Timer runs → Child stops timer → Points calculated → Parent approves (optional)
+```
+
+Points are awarded based on a **rate**: X points per Y minutes. A 30-minute reading session at 10 points per 5 minutes earns 60 points.
+
+---
+
+## Configuring a Timed Task
+
+When creating or editing a chore, set the **Task Type** to `timed`. Three additional fields appear:
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Timed Rate Points** | `10` | Points awarded per rate window |
+| **Timed Rate Minutes** | `5` | Size of the rate window in minutes |
+| **Daily Cap (minutes)** | `0` | Maximum minutes per day. `0` = unlimited. |
+
+**Example:** Rate = 10 points per 5 minutes. A child who reads for 23 minutes earns `(23 ÷ 5) × 10 = 40 points` (partial windows are dropped, not rounded up).
+
+**Formula:** `floor(total_seconds / (rate_minutes × 60)) × rate_points`
+
+---
+
+## The Timer Workflow
+
+### Starting
+
+1. Child taps **Start** on the timed chore in the child card
+2. A live timer appears showing elapsed time
+3. The session state is `running`
+
+### Pausing
+
+1. Child taps **Pause** — the timer freezes
+2. The session state becomes `paused`
+3. Child can resume later by tapping **Start** again
+4. Multiple start/pause cycles are tracked as separate segments
+
+### Stopping
+
+1. Child taps **Stop** — the session ends
+2. Total elapsed time is calculated from all segments
+3. If the chore requires approval, a completion is created as pending
+4. If no approval required, points are awarded immediately
+
+### Daily Cap
+
+When `timed_max_daily_minutes` is set (non-zero):
+
+- The timer cannot be started once the cap is reached
+- If the session would exceed the cap, the duration is clamped to the remaining allowance
+- The daily cap resets at midnight
+
+---
+
+## Session Model
+
+Each active timer is tracked as a `TimedSession`:
+
+| Field | Description |
+|-------|-------------|
+| `state` | `running`, `paused`, or `stopped` |
+| `segments` | List of `{start, end}` time windows |
+| `total_seconds_today` | Cumulative elapsed seconds for the day |
+| `session_date` | ISO date the session belongs to |
+
+Sessions from previous days are automatically stopped and submitted at midnight.
+
+---
+
+## Services
+
+### `taskmate.start_timed_task`
+
+Start or resume a timed task timer.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `chore_id` | Yes | ID of the timed chore |
+| `child_id` | Yes | ID of the child |
+
+```yaml
+service: taskmate.start_timed_task
+data:
+ chore_id: b3f9a12c
+ child_id: a8c8376a
+```
+
+### `taskmate.pause_timed_task`
+
+Pause a running timer. The child can resume later.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `chore_id` | Yes | ID of the timed chore |
+| `child_id` | Yes | ID of the child |
+
+```yaml
+service: taskmate.pause_timed_task
+data:
+ chore_id: b3f9a12c
+ child_id: a8c8376a
+```
+
+### `taskmate.stop_timed_task`
+
+Stop the timer and submit for approval. Points are calculated from total elapsed time.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `chore_id` | Yes | ID of the timed chore |
+| `child_id` | Yes | ID of the child |
+
+```yaml
+service: taskmate.stop_timed_task
+data:
+ chore_id: b3f9a12c
+ child_id: a8c8376a
+```
+
+---
+
+## Child Card Display
+
+The child card shows timed tasks differently from standard chores:
+
+- **Not started:** Shows Start button with the rate info (e.g. "10 pts / 5 min")
+- **Running:** Shows a live elapsed timer, Pause button, and Stop button
+- **Paused:** Shows frozen elapsed time, Start (resume) button, and Stop button
+- **Stopped/completed:** Shows the earned points and duration
+
+---
+
+## Sensor Attributes
+
+Active timed sessions appear in the activity sensor:
+
+| Attribute | Description |
+|-----------|-------------|
+| `active_timed_sessions` | List of running/paused sessions with `chore_id`, `child_id`, `state`, `total_seconds_today`, `current_segment_start` |
+
+Completion records for timed tasks include:
+
+| Field | Description |
+|-------|-------------|
+| `timed_duration_seconds` | Total elapsed seconds for the session |
+
+---
+
+## Midnight Behaviour
+
+- Stale sessions from previous days are automatically stopped and submitted
+- A completion record is created with the elapsed time up to midnight
+- The daily cap resets for the new day
+
+---
+
+## Tips
+
+- **Set reasonable caps** for young children — 30 or 60 minutes prevents gaming the system
+- **Use generous rate windows** (e.g. 10 pts per 15 min) for activities where sustained effort matters more than speed
+- **Combine with approval** so parents can verify the child was actually doing the activity, not just running the timer
+
+---
+
+## Related
+
+- [Chores](Chores.md) — chore configuration including task_type
+- [Services](Services.md) — full service reference
+- [Dashboard Cards](Dashboard-Cards.md) — child card timer display
diff --git a/wiki/Timed-Unlock-Rewards.md b/wiki/Timed-Unlock-Rewards.md
new file mode 100644
index 00000000..a37fefea
--- /dev/null
+++ b/wiki/Timed-Unlock-Rewards.md
@@ -0,0 +1,70 @@
+# Timed Unlock Rewards
+
+Spend points to unlock something for a while — the TV, the console socket, a wifi group. Approving the claim turns the entity on; a timer turns it back off.
+
+
+
+---
+
+## Two Deliberate Limits
+
+This is the one TaskMate feature that reaches out and changes your house, so it is deliberately narrow:
+
+1. **A reward can only turn one entity on and back off.** There is no free-form service call, no payload, no template.
+2. **The entity must be on your allowlist.**
+
+An empty allowlist permits **nothing**. This gates household devices, so the safe default when unconfigured is "no".
+
+---
+
+## Setting It Up
+
+**1. Settings → Unlock allowlist**
+
+Add the entities a reward may touch. An entry can be:
+
+- a full entity id — `switch.xbox`
+- a bare domain — `switch`, to permit everything in it
+
+**2. Open a reward → Advanced — timed unlock**
+
+Pick an allowlisted entity and a duration, up to 24 hours. `0` leaves it on for you to turn off yourself.
+
+---
+
+## Key Points
+
+- **The allowlist is checked twice** — when the reward is saved, and again when it fires. You can revoke an entity later and any reward pointing at it quietly stops unlocking rather than breaking.
+- **Active unlocks are persisted.** A Home Assistant restart mid-unlock re-arms the timer; anything already past due is turned off at startup. A restart can never strand the television on.
+- **Turning something off is never gated by the allowlist.** A revert is always safe, so removing an entity from the allowlist can't trap it in the on state.
+
+---
+
+## Events
+
+| Event | Fired when |
+|-------|-----------|
+| `taskmate_unlock_started` | The unlock begins |
+| `taskmate_unlock_ended` | The timer reverts it |
+
+Both carry `entity_id`, `reward_id`, `reward_name`, `child_id`, `child_name`, `started_at` and `revert_at`.
+
+---
+
+## Examples
+
+| Reward | Entity | Duration |
+|--------|--------|----------|
+| One hour of Xbox | `switch.xbox_socket` | 60 min |
+| Film night | `switch.living_room_tv` | 180 min |
+| Extra wifi after bedtime | `switch.kids_wifi` | 30 min |
+
+---
+
+## Related
+
+- [Rewards](Rewards.md) — costs, jackpots, spending caps and the claim flow
+- [Managing Rewards](Managing-Rewards.md) — the parent approval workflow
+- [Settings](Settings.md) — the unlock allowlist
+- [Insights](Insights.md) — the health report flags a reward whose entity has left the allowlist
+- [Automations](Automations.md) — every TaskMate bus event
diff --git a/wiki/To-Do-Lists.md b/wiki/To-Do-Lists.md
new file mode 100644
index 00000000..277401bf
--- /dev/null
+++ b/wiki/To-Do-Lists.md
@@ -0,0 +1,67 @@
+# To Do Lists
+
+TaskMate publishes each child's outstanding chores as a native Home Assistant **To-do list**, so you can see and tick off today's chores using HA's built-in To-do List card — and through any voice assistant — without the custom TaskMate cards.
+
+
+
+---
+
+## What You Get
+
+For every child, TaskMate creates one to-do list entity:
+
+```
+todo.taskmate_
+```
+
+For example, a child called Malia gets `todo.taskmate_malia`. New children get their own to-do list automatically as soon as they're added.
+
+Each list shows the chores that child **still needs to do today** — the same set of due chores TaskMate uses everywhere else (it shares the integration's due-chore logic, so vacation mode, scheduling, availability and dynamic visibility are all honoured). Completed chores drop off the list.
+
+---
+
+## Ticking Items Off Completes the Chore
+
+The list isn't just a read-only mirror. When you (or a child, or a voice assistant) **check an item off**, TaskMate marks that chore as completed for that child — exactly as if it had been completed from the child card. Points are awarded and the usual approval flow applies where configured.
+
+This makes the native To-do List card a fully working way to drive TaskMate from anywhere in your Home Assistant dashboards.
+
+> The to-do list supports updating items (checking them off). Items are added and removed by TaskMate itself based on what's due — you don't add chores from the to-do card; create them in the [Admin Panel](Admin-Panel.md) as usual. See [Chores](Chores.md).
+
+---
+
+## Adding the To-do List Card
+
+Use Home Assistant's built-in **To-do List** card and point it at the child's list:
+
+```yaml
+type: todo-list
+entity: todo.taskmate_malia
+```
+
+To show several children at once, stack one card per child (for example in a grid or vertical stack):
+
+```yaml
+type: vertical-stack
+cards:
+ - type: todo-list
+ entity: todo.taskmate_malia
+ - type: todo-list
+ entity: todo.taskmate_alex
+```
+
+For TaskMate's own richer cards, see [Dashboard Cards](Dashboard-Cards.md).
+
+---
+
+## Voice Assistants
+
+Because these are standard HA to-do lists, they work with voice assistants for free. You can ask Assist what's on a child's list and mark items done by voice, alongside TaskMate's dedicated voice intents. See [Voice Assistants](Voice-Assistants.md).
+
+---
+
+## See Also
+
+- [Chores](Chores.md) — creating and scheduling the chores that appear here
+- [Dashboard Cards](Dashboard-Cards.md) — TaskMate's own child cards
+- [Voice Assistants](Voice-Assistants.md) — asking about and completing chores by voice
diff --git a/wiki/Troubleshooting.md b/wiki/Troubleshooting.md
new file mode 100644
index 00000000..660e2d06
--- /dev/null
+++ b/wiki/Troubleshooting.md
@@ -0,0 +1,329 @@
+# Troubleshooting
+
+## Cards Show "Custom element doesn't exist"
+
+The Lovelace resources haven't loaded yet.
+
+**Fix:**
+1. Hard refresh the browser: **Cmd+Shift+R** (Mac) or **Ctrl+Shift+R** (Windows/Linux)
+2. If that doesn't work, check **Settings → Dashboards → Resources** — the `/taskmate/*.js` entries should be listed
+3. If the resources are missing, restart Home Assistant — they are registered automatically on startup
+
+---
+
+## Cards Show "Entity not found: sensor.taskmate_overview"
+
+The entity name is wrong or the integration isn't loaded.
+
+**Fix:**
+1. Go to **Developer Tools → States** and search for `taskmate` — verify the entity exists
+2. Make sure you're using `sensor.taskmate_overview` (not `sensor.taskmate_pending_approvals`)
+3. If the entity doesn't exist, check **Settings → Devices & Services** — is TaskMate listed?
+4. If TaskMate is listed but entities are missing, try reloading the integration
+
+---
+
+## Cards Render as Empty Boxes
+
+JavaScript is failing to parse. Usually caused by a corrupted or outdated JS file.
+
+**Fix:**
+1. Open browser DevTools (F12) → Console tab — look for errors mentioning `taskmate-*.js`
+2. Check the error message — `Unexpected token '}'` indicates a JS syntax error
+3. Hard refresh after deploying new card files
+4. Verify the file sizes are correct — files under ~1KB are likely corrupted
+
+---
+
+## Child Card Blank on an Older iPhone or iPad
+
+On iOS 15 (Safari 16.3 and older, including the Home Assistant companion app on those devices), the Child Card showed nothing from v6.0.0 to v6.1.0, while the other cards still worked.
+
+**Fix:** update TaskMate to **v6.2.0** or later, then hard refresh or restart the companion app.
+
+---
+
+## Resources Keep Disappearing After Restart
+
+This was a known issue that has been fixed across two releases:
+
+**v1.1.2** — The resource manager was accidentally deleting entries it couldn't match. The delete logic was removed entirely — the manager now only ever adds or updates, never deletes.
+
+**v1.1.6** — A deeper root cause was identified. `ResourceStorageCollection` is lazy and doesn't load from disk until forced. TaskMate was reading resources before the storage had loaded, getting an empty list, writing all 13 entries, and then having them wiped when Lovelace loaded its own storage file shortly after. The fix forces the storage to load before TaskMate touches anything — the same approach used by the WebRTC and Browser Mod integrations.
+
+**Fix:** Update to v1.1.6 or later. If you are already on v1.1.6+ and resources are still disappearing, check `Settings → System → Logs` (filter by `taskmate`) for error messages from the resource manager.
+
+---
+
+## Chore Description Not Showing
+
+**Checklist:**
+1. The chore must have a description set — open the **TaskMate** panel → **Chores**, edit the chore, check the Description field
+2. **Show chore description** must be enabled in the child card editor (it's off by default)
+
+---
+
+## Points Not Updating After Completing a Chore
+
+If the chore has **Requires Approval** turned on:
+- Points are held as "pending" until a parent approves
+- The child card header shows a "Pending" section with the held points
+- Approve the completion from the Parent Dashboard card or Approvals card
+
+If the chore does **not** require approval and points still aren't updating:
+- Check Developer Tools → States → `sensor.taskmate_overview` → `children` array — is the child's `points` value changing?
+- The sensor updates every 30 seconds — wait a moment and refresh
+
+---
+
+## Streak Not Incrementing
+
+**Things to check:**
+- Streaks are updated at **midnight** — if you complete chores and check before midnight, the streak won't have incremented yet
+- The streak increments the next day when the overnight check confirms yesterday had a completion
+- If **Streak Reset Mode** is `reset` and a day was missed, the streak resets to 0
+
+---
+
+## Streak Reset to Zero Unexpectedly
+
+- Check the **Streak Reset Mode** in Settings — if set to `reset`, any missed day resets the streak
+- Change to `pause` if you want streaks to be preserved across missed days
+- Streaks are based on the child's `last_completion_date` compared to today's date in the HA timezone — timezone issues can cause false resets
+
+---
+
+## Wrong Timezone on Chore Completions
+
+TaskMate uses the Home Assistant configured timezone for all date comparisons.
+
+**Fix:**
+1. Check your HA timezone: **Settings → System → General → Time Zone**
+2. Ensure it matches your actual timezone
+3. The `today_day_of_week` attribute on `sensor.taskmate_overview` shows the current day in HA timezone — verify it's correct
+
+---
+
+## Reward Cost Seems Wrong
+
+All reward costs are fixed values set by the parent — there is no dynamic calculation.
+
+**Checklist:**
+1. Open the **TaskMate** panel → **Rewards** → edit the reward → check the **Points cost** field
+2. Verify the child has enough points — check `sensor.taskmate_overview` → `children` → `points` for that child
+3. If the child has a pending reward claim, those points are committed and shown as `committed_points` — they can't be used for another claim until the first is approved or rejected
+
+---
+
+## Fart Sounds Not Playing
+
+**Checklist:**
+1. The `.mp3` files must be in `/config/www/taskmate/`
+2. Files must be named exactly `fart1.mp3` through `fart10.mp3`
+3. Try `taskmate.preview_sound` with `sound: fart1` in Developer Tools to test
+4. Browser autoplay policies may block audio until the user has interacted with the page — tap something first
+
+---
+
+## Integration Fails to Load
+
+**Check the logs:**
+
+Settings → System → Logs → search for `taskmate`
+
+Common errors:
+- `ImportError` — a dependency is missing. Try restarting HA or reinstalling the integration
+- `ValueError` in storage — storage data may be corrupted. Check `/config/.storage/taskmate.storage.*`
+- `Lovelace not available` — the lovelace integration hasn't loaded yet. Usually resolves on next restart
+
+---
+
+## Getting More Debug Information
+
+Enable debug logging for TaskMate:
+
+```yaml
+# configuration.yaml
+logger:
+ logs:
+ custom_components.taskmate: debug
+```
+
+Restart HA and check **Settings → System → Logs** for detailed output from the coordinator, storage, and resource manager.
+
+---
+
+## Notifications Not Working
+
+**Persistent notifications not appearing:**
+- Check **Settings → System → Logs** for `TaskMate: failed to send notification` errors
+- Verify the chore has **Requires Approval** turned on — notifications only fire for approval-required chores
+- Chores that auto-approve (Requires Approval = off) never trigger a notification
+
+**Push notifications not arriving:**
+- Go to the **TaskMate** panel → **Settings** and verify the Notification Service is set correctly
+- The format must be `notify.service_name` e.g. `notify.mobile_app_johns_phone`
+- Test the service directly: **Developer Tools → Services** → call `notify.mobile_app_johns_phone` with a test message
+- If you want to notify multiple people, create a notify group in `configuration.yaml` and use `notify.group_name`
+
+---
+
+## Recurring Chore Not Appearing / Still Locked
+
+**Chore shows as dimmed or hidden after completing it:**
+- This is correct behaviour for recurring chores — the window hasn't reset yet
+- The `recurrence_done_mode` on the child card controls whether it's dimmed or hidden
+- Check `sensor.taskmate_overview` → `chores` → find the chore → check `is_available` for your child's ID
+
+**Chore never becomes available:**
+- If **Wait for First Scheduled Occurrence** is set, the chore is locked until the first scheduled day arrives
+- For Every 2 Days with a future start date, the chore is locked until that date
+
+**Window reset earlier than expected:**
+- Check if the chore was completed and then undone — undo restores the previous completion as the anchor
+- The `history_days` setting does not affect recurrence — the `last_completed` store is separate and never pruned
+
+---
+
+## Timed Task Timer Not Starting
+
+**Checklist:**
+1. The chore must have `task_type` set to `timed` — edit the chore and verify
+2. If a daily cap is set, check whether the child has already reached it today
+3. Check for an existing stale session — if one exists from a previous day, it should be auto-cleaned at midnight
+4. Verify the chore is assigned to the child and available today
+
+---
+
+## Timed Task Points Seem Wrong
+
+Points are calculated as `floor(total_seconds / (rate_minutes × 60)) × rate_points`. Partial windows are dropped, not rounded.
+
+**Example:** 23 minutes at 10 pts / 5 min = `floor(23/5) × 10 = 40 points` (not 46).
+
+If the daily cap is set, the duration is clamped before calculation.
+
+---
+
+## Task Group Not Coordinating Assignments
+
+**Checklist:**
+1. Task groups only work with rotation modes (`alternating`, `random`, `balanced`) — chores in `everyone` mode are unaffected
+2. For sticky groups, the first chore in `chore_ids` is the leader — check the order
+3. If the leader's assigned child is not in a follower's pool, the follower falls back to independent rotation
+4. Verify the group exists — check `sensor.taskmate_incentives` → `task_groups`
+
+---
+
+## Bonus Subtask Not Appearing
+
+**Checklist:**
+1. The parent chore must be completed by the same child today before subtasks unlock
+2. Verify the chore has bonus subtasks configured — check `sensor.taskmate_chores` → find the chore → `bonus_subtasks`
+3. Each subtask can only be completed once per child per day
+
+---
+
+## Admin Panel Not Showing in Sidebar
+
+**Checklist:**
+1. The panel requires an **admin** HA user — non-admin users will not see it
+2. Try restarting Home Assistant — the panel is registered on integration setup
+3. Check logs for errors related to `panel_custom` or `taskmate-panel`
+
+---
+
+## "State attributes … exceed maximum size of 16384 bytes" in the Log
+
+```
+WARNING (Recorder) [homeassistant.components.recorder.db_schema] State attributes
+for sensor.taskmate_activity exceed maximum size of 16384 bytes. This can cause
+database performance issues; Attributes will not be stored
+```
+
+**Fixed in v5.3.0 — upgrade.** TaskMate's sensors carry large lists (recent
+completions, pending approvals, the chore catalogue). Home Assistant's recorder
+refuses to store any attribute payload over 16 KB and, when it hits that limit,
+discards the entity's *entire* attribute set for that state. Larger families hit
+it easily, most visibly right after approving a batch of chores.
+
+From v5.3.0 those lists are declared unrecorded, so the recorder skips them and
+the warning stops. Nothing you use changes — the lists are still on the live
+state, so cards, templates and automations are unaffected. See
+[Attributes and the recorder](Sensor-Attributes.md#attributes-and-the-recorder-v530).
+
+If you still see the warning after upgrading, check the entity named in the
+message: if it is not a `sensor.taskmate_*` entity, it belongs to a different
+integration.
+
+---
+
+## "image_url must be a TaskMate image URL" When Saving a Chore
+
+```
+Error handling message: image_url must be a TaskMate image URL for dictionary
+value @ data['image_url']. Got '/api/taskmate/image/.jpg?authSig=eyJhbGciOi…'
+(invalid_format)
+```
+
+**Fixed in v5.4.1 — upgrade.** Adding a picture to a chore worked, but every
+later edit of that chore was rejected with this error and the change was lost,
+so the chore looked permanently uneditable.
+
+TaskMate signs chore image URLs before sending them to the admin panel, because
+a browser does not attach the Home Assistant bearer token to a plain ` `
+request — an unsigned URL would return 401 and the picture would never appear.
+The chore editor filled its form from that state and sent the signed value back
+on save, while the save-side check only accepted the bare
+`/api/taskmate/image/.jpg` form. Uploading a new image succeeded because
+the upload response is unsigned; only re-saving an existing one failed.
+
+From v5.4.1 the signature is stripped and the bare path validated when the chore
+is saved, so only the canonical URL is stored. Nothing needs re-uploading —
+existing chores and their images are unaffected, and a chore whose edits were
+failing will simply save after upgrading.
+
+---
+
+## Rewards Card Disappears When a Child Claims a Reward
+
+The rewards card renders as an empty space — no header, no rewards, nothing —
+from the moment a child claims a reward until a parent approves or rejects it.
+Approving the claim brings the whole card back as if nothing had happened. An
+approvals card set to a single child goes blank at the same time, and the parent
+dashboard's pending total reads `NaN`.
+
+**Fixed in v5.4.2 — upgrade.** Nothing in your configuration causes this and
+nothing needs changing; in particular it is unrelated to renaming your points,
+which several people reasonably suspected because the two often coincide.
+
+Two sensors were publishing different data under one attribute name.
+`sensor.taskmate_rewards` uses `pending_reward_claims` for the *list* of pending
+claims, while `sensor.taskmate_pending_approvals` used the same name for a plain
+*count*. Cards read attributes through a resolver that merges the companion
+sensors over the primary one, and the approvals sensor merges last — so the
+number replaced the list. The cards then filtered a number, the render threw,
+and Home Assistant leaves a card whose render fails as blank space.
+
+It only showed up once something was actually pending: with no claims the count
+is `0`, which is falsy, so the cards' own fallback quietly substituted an empty
+list and everything worked. Present from **v5.2.0**, when the companion sensor
+id was corrected and the colliding attribute started being merged at all.
+
+From v5.4.2 the resolver refuses to merge the approvals sensor's three count
+attributes, and the cards coerce the value to a list before using it. The counts
+are unchanged on `sensor.taskmate_pending_approvals` itself and still work in
+templates and automations.
+
+---
+
+## Reporting a Bug
+
+If you've confirmed it's a TaskMate bug, open an issue at:
+**https://github.com/tempus2016/taskmate/issues**
+
+Include:
+- TaskMate version (visible in Settings → Devices & Services → TaskMate)
+- Home Assistant version
+- Relevant log output with debug logging enabled
+- Steps to reproduce
diff --git a/wiki/Two-Way-Calendar.md b/wiki/Two-Way-Calendar.md
new file mode 100644
index 00000000..53442417
--- /dev/null
+++ b/wiki/Two-Way-Calendar.md
@@ -0,0 +1,93 @@
+# Two Way Calendar
+
+The per-child TaskMate calendars used to be read-only. Now you can **plan chores straight from Home Assistant's calendar**: add an event to create a one-off chore, drag a chore to another day, or delete a single day to skip it.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## Who Can Edit
+
+Only **parents and admins** can change a TaskMate calendar. Anyone else gets a permission error. Automations and scripts that run without a user are allowed, the same as elsewhere in TaskMate.
+
+Every change is checked by TaskMate first, then written to the [Admin Audit Log](Admin-Audit-Log.md).
+
+---
+
+## Adding a Chore
+
+Create an event on a child's calendar (`calendar.taskmate_`), either in Home Assistant's **Calendar** page or with the `calendar.create_event` action. TaskMate turns it into a **one-off chore** for that child on that date.
+
+| Event | Resulting chore |
+|-------|-----------------|
+| **Title** | The chore's name |
+| **Has a start time** | The chore gets that **due time**, and goes into the time-of-day period that contains it |
+| **All day** | An *anytime* chore |
+| **Points** | The standard **10**. Change them in the TaskMate panel afterwards if you like. |
+
+These are refused, with a clear message:
+
+- Repeating events
+- Dates in the past
+- An empty title
+
+```yaml
+action: calendar.create_event
+target:
+ entity_id: calendar.taskmate_mia
+data:
+ summary: Clear out the garage
+ start_date_time: "2026-09-30 10:00:00"
+ end_date_time: "2026-09-30 10:30:00"
+```
+
+---
+
+## Moving a Chore
+
+Drag a chore to another day in the calendar, or edit its date.
+
+| Chore | What moves |
+|-------|------------|
+| **Repeating chore** | Only that one day. The rest of the schedule stays put. |
+| **One-off chore** | The chore itself. Its title and time can change too. |
+
+Chores with a due time show in the calendar as a 30-minute event at that time, so you can drag them to the same time on another day.
+
+A moved occurrence is honoured everywhere: the child card, reminders, the Today board, streaks, perfect weeks, [mandatory](Mandatory-Chores.md) misses, the ICS feed and any calendars the chore is published to. Completing a moved chore counts for the day it was originally due, so it doesn't knock the next occurrence out of place.
+
+### What you can't change from the calendar
+
+These are refused, with a message telling you to edit the chore in the TaskMate panel instead:
+
+- Moving a **whole series** (the "this and all future events" choice)
+- **Renaming** a repeating chore
+- Changing a repeating chore's **time of day**
+- Moving a chore **into the past**
+
+---
+
+## Skipping a Day
+
+Delete a single occurrence to **skip just that day**. The chore carries on as normal on every other day.
+
+Deleting a one-off chore switches it off, the same way it's switched off once its day has passed.
+
+---
+
+## Shared Chores
+
+A move or skip applies to the **chore**, not to one child. If the chore is shared by several children, moving it on Mia's calendar moves it for everyone who shares it, and it moves on all their calendars.
+
+"Away" blocks (vacation and unavailable days) are still read-only.
+
+---
+
+## Related
+
+- [Calendar](Calendar.md) — the per-child calendar entities and ICS feed
+- [Chore Scheduling](Chore-Scheduling.md) — repeating and one-off chores
+- [Chores](Chores.md) — editing a chore in the TaskMate panel
+- [Admin Audit Log](Admin-Audit-Log.md) — where calendar changes are recorded
diff --git a/wiki/Vacation-Mode.md b/wiki/Vacation-Mode.md
new file mode 100644
index 00000000..64c2eff7
--- /dev/null
+++ b/wiki/Vacation-Mode.md
@@ -0,0 +1,80 @@
+# Vacation Mode
+
+Vacation mode lets you mark date ranges as time off. During a vacation, all chores are paused and streaks are frozen — days inside a vacation never count as missed, so a streak survives a holiday.
+
+
+
+---
+
+## What a Vacation Does
+
+While today falls inside a vacation period:
+
+- **All chores are paused** — every chore reports as unavailable, so children see nothing to do (the child card shows an on-vacation banner instead of the chore list).
+- **Streaks are frozen** — the nightly streak check is skipped entirely on a vacation day. No streak is reset or paused.
+- **Missed days are forgiven** — when the streak check next runs, any vacation days between a child's last completion and today are not counted as misses. A genuine, non-vacation day that was missed still breaks the streak as normal.
+
+Away days also surface as multi-day all-day **"Away"** events on each child's [Calendar](Calendar.md).
+
+---
+
+## Three Ways to Mark Time Off
+
+From v4.1.0 a child can be treated as away from any of three stacking sources, OR'd together. The first two are **global** (they apply to every child); the third is **per-child**.
+
+1. **Static vacation periods** (`vacation_periods`) — named date ranges you define by hand. Historical date math: a day counts as away when it falls inside any period.
+2. **Calendar-synced vacations** (`vacation_calendar`) — point the setting at a Home Assistant `calendar.*` entity and TaskMate follows it live: whenever that calendar has an active event, every child is treated as away for as long as the event runs. Fail-open — a missing or broken entity never freezes anyone. Leave the setting empty to disable.
+3. **Per-child availability** — a child who opts in with `pause_streak_when_unavailable` is treated as away whenever their own availability sensor (which may itself be a `calendar.*` entity) reports them unavailable. This affects only that child.
+
+While a child is away — from any source — their **streak is paused**: no streak break, and no missed-mandatory penalties pile up for those days.
+
+---
+
+## Setting Up a Vacation
+
+Add and remove vacation periods in the [Admin Panel](Admin-Panel.md) under **Settings**, using the vacation editor. Each period has:
+
+| Field | Description |
+|-------|-------------|
+| **Name** | Optional label (e.g. "Summer holiday") |
+| **Start** | First day of the vacation (inclusive) |
+| **End** | Last day of the vacation (inclusive) |
+
+Both bounds are inclusive ISO dates. If you enter the end before the start, TaskMate swaps them automatically. Up to 50 periods can be stored.
+
+Periods are saved in the `vacation_periods` setting as a list of `{ id, name, start, end }` entries, sorted by start date.
+
+---
+
+## What Resumes Afterwards
+
+There is nothing to switch back on. The moment the current date moves past a vacation's end date:
+
+- Chores become available again on their normal schedule.
+- The nightly streak check runs again. Because the vacation days were forgiven, a child who was on a streak before the holiday keeps it — completing on the first day back continues the run.
+
+---
+
+## Sensor Attributes
+
+Both `sensor.taskmate_overview` and the chores sensor expose the current vacation state:
+
+| Attribute | Description |
+|-----------|-------------|
+| `vacation_active` | `true` if today is inside any vacation period |
+| `vacation_name` | Name of the active period (empty if none) |
+| `vacation_end` | End date of the active period (empty if none) |
+
+`sensor.taskmate_overview` additionally exposes `vacation_periods` — the full validated list, for cards or automations that want to show upcoming time off.
+
+---
+
+## Guests Use the Same Mechanism
+
+When a [guest profile](Guest-Child-Profiles.md) reaches its end date it is **archived**, which reuses this same availability path. Every chore, streak and rotation rule already treats an archived guest exactly as it treats a child who is away — there is no second code path that could disagree.
+
+## Related
+
+- [Calendar](Calendar.md) — "Away" events on the per-child calendars
+- [Chores](Chores.md) — chore availability
+- [Bonus Points](Bonus-Points.md) — streak milestones and perfect-week bonuses that vacations protect
diff --git a/wiki/Virtual-Pets.md b/wiki/Virtual-Pets.md
new file mode 100644
index 00000000..d7ac0e09
--- /dev/null
+++ b/wiki/Virtual-Pets.md
@@ -0,0 +1,199 @@
+# Virtual Pets
+
+Every child can look after a virtual pet that grows up as they do their chores. It starts as an egg, hatches into a baby and grows bigger with every job they finish. Once it is fully grown there is still more to work towards: a home to fill, a legendary golden coat, an egg that hatches into the next pet, and pet levels. It's a gentler motivator than a streak for younger children, because nothing is ever lost: a sleepy pet perks up again with the next chore.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Turning Pets On
+
+Pets are off until you switch them on:
+
+**TaskMate panel → Settings → Virtual pets → Turn on virtual pets**
+
+The same section holds every growth number described below. While pets are off, the Pet card says so and nothing about a pet is shown or counted.
+
+---
+
+## Adopting a Pet
+
+The child adopts their pet on the [Pet card](#the-pet-card): they pick one of six creatures (dragon, cat, dog, bunny, dino or unicorn), give it a name and tap **Adopt!**
+
+
+
+The pet starts as an egg and only counts chores finished **from adoption onwards**, so a child who has been using TaskMate for a year doesn't get a fully grown pet on day one.
+
+Adopting again (the `adopt_pet` service with a new species or name) renames or re-chooses the pet but keeps its growth: it's still the same friend.
+
+---
+
+## How It Grows
+
+Every finished chore adds **growth**. By default:
+
+- each chore is worth **10 growth**, and
+- every point the child **earns** adds **1 growth**, so a big job grows the pet faster than a quick one.
+
+Spending points never shrinks the pet: growth counts points earned, not the balance.
+
+The pet moves through five stages, each drawn as its own picture:
+
+
+
+| Stage | Card shows | Default growth | Roughly (5-point chores) |
+|-------|-----------|----------------|--------------------------|
+| Egg | "A dragon egg" | 0 | at adoption |
+| Baby | "Baby dragon" | 30 | 2 chores |
+| Little | "Little dragon" | 200 | 13 chores |
+| Big | "Big dragon" | 600 | 40 chores |
+| Fully grown | "Fully grown dragon" | 1500 | 100 chores |
+
+Babies are all head and eyes. As the pet grows it gets a body, legs and finally its grown-up features: wings and horns for the dragon, a mane for the unicorn, a collar for the dog, and so on.
+
+A progress bar under the pet shows how far it is to the next thing ("35% of the way to: Big dragon").
+
+### It never goes backwards
+
+A stage, a legendary coat, a home item or a pet level, once reached, is kept. Undoing a chore or raising one of the numbers in Settings leaves the pet where it got to; it just takes longer to reach the next step.
+
+---
+
+## Moods
+
+The pet's mood follows the child's last chore:
+
+| Mood | When | What the card says |
+|------|------|--------------------|
+| **Happy** | A chore was done today | "Pip is happy — you did a chore today!" |
+| **Proud** | A chore today and a streak of 7 days or more | "Pip is SO proud of your streak! ✨" |
+| **Content** | The last chore was yesterday | "Pip is resting. A chore today will cheer them up." |
+| **Sleepy** | Longer than that | "Pip is sleepy… do a chore to wake them up!" |
+
+Days away don't make a pet sleepy: on a [vacation](Vacation-Mode.md) or a [sick day](Sick-Days.md) the pet stays content, because the child was meant to rest.
+
+Tapping the pet gives it a cuddle: a little hop and some hearts. Nothing is saved.
+
+---
+
+## Accessories
+
+Accessories are unlocked by the **child's** [level](Levels-and-XP.md), not the pet's growth:
+
+| Accessory | Unlocks at |
+|-----------|------------|
+| 🎀 Bow | Level 3 |
+| 🎩 Top hat | Level 8 |
+| 🧣 Scarf | Level 15 |
+| 👑 Crown | Level 25 |
+
+The pet wears every accessory the child has unlocked. Locked ones show greyed out on the card with the level they need.
+
+---
+
+## After Fully Grown
+
+Once the pet is fully grown, four things can keep it going. Each one can be switched on or off and tuned under **Settings → Virtual pets → After fully grown**. The numbers are **total growth since adoption**, so they always come after the "Fully grown" number. Turning one off only hides it; nothing earned is lost.
+
+| Extra | Default | What happens |
+|-------|---------|--------------|
+| **Its home grows** | on, a new item every 300 growth | The pet's home fills up: grass, a cushion, flowers, a tree, a pond and more, up to 10 items |
+| **Turns legendary** | on, at 3000 growth | The pet turns gold and sparkles. The big goal after fully grown |
+| **Lays an egg** | on | The pet lays an egg the child can hatch into a new pet. With legendary on, the egg comes with legendary; with legendary off it comes at the **Egg at** number (3000 by default) |
+| **Pet levels** | off, a new level every 300 growth | A level badge on the card that keeps going up |
+
+### Eggs and the pet family
+
+When the pet lays an egg, the card shows **Hatch the egg**. The child picks a creature and a name, and the new pet starts again from an egg. The previous pet joins the **Pet family** row at the bottom of the card, legendary ones still in gold.
+
+**Largest pet family** (6 by default, 2–12) caps how many pets a child can have, counting the current one. Once the family is full, no more eggs are laid.
+
+---
+
+## Parent Settings
+
+
+
+| Setting | Key | Default | Description |
+|---------|-----|---------|-------------|
+| Turn on virtual pets | `pets_enabled` | off | Master switch |
+| Growth per chore | `pet_xp_per_chore` | `10` | Growth for every finished chore (0–1000) |
+| Chore points count too | `pet_points_count` | on | Each point earned adds 1 growth |
+| Hatches (baby) | `pet_stage_baby` | `30` | Growth to hatch |
+| Little | `pet_stage_kid` | `200` | |
+| Big | `pet_stage_teen` | `600` | |
+| Fully grown | `pet_stage_grown` | `1500` | |
+| Its home grows | `pet_home_enabled` | on | |
+| New home item every | `pet_home_every` | `300` | |
+| Turns legendary | `pet_legendary_enabled` | on | |
+| Legendary at | `pet_legendary_at` | `3000` | |
+| Lays an egg | `pet_eggs_enabled` | on | |
+| Egg at | `pet_egg_at` | `3000` | Used only when legendary is off |
+| Largest pet family | `pet_family_max` | `6` | 2–12, counting the current pet |
+| Pet levels | `pet_levels_enabled` | off | |
+| New level every | `pet_level_every` | `300` | |
+
+Each stage number must be higher than the one before, and legendary and the egg must come after fully grown; the panel won't save numbers that break the order. Beside each number the panel shows roughly how many 5-point chores it takes. **Reset numbers to defaults** puts them all back.
+
+If growth per chore is 0 and points don't count, pets can't grow, and the panel warns you.
+
+---
+
+## The Pet Card
+
+**Edit dashboard → + Add Card → TaskMate Pet**
+
+```yaml
+type: custom:taskmate-pet-card
+entity: sensor.taskmate_overview
+child_id: 8e16ad66b23f404e
+```
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `entity` | string | **required** | The TaskMate overview sensor |
+| `child_id` | string | **required** | Whose pet this is. Find IDs in the panel with **Show IDs** switched on |
+| `title` | string | the pet's name | Card title. Before adoption it reads "My pet" |
+| `card_design` | string | global default | `classic`, `playroom`, `console`, `cleanpro`, `accessible` or `graphite` |
+| `header_color` | string | `#16a085` | Header banner colour (YAML only) |
+
+Before adoption the card is the adoption form. After that it shows the pet in its current stage and mood, the progress bar to the next goal, the accessories, the **Hatch the egg** box when an egg is ready, and the pet family.
+
+The first time a device sees the pet reach something new (a stage, legendary, an egg, a home item or a level) the card plays a short "evolving" moment, once per device.
+
+---
+
+## Notification and Event
+
+The **Pet grew up** notification (off by default; switch it on under **Notifications**) tells the child and/or parents when a pet:
+
+- reaches its next stage: "🐣 Pip just grew up! Have a look at Vaiha's pet."
+- turns legendary: "✨ Sparkle turned legendary! Vaiha's pet is shining gold."
+- lays an egg: "🥚 Sparkle laid an egg! Vaiha can hatch a new pet."
+- reaches a new pet level: "💖 Sparkle reached pet level 4!"
+
+Every one of these fires the `taskmate_pet_evolved` event whether or not the notification is on. Its data includes `child_id`, `child_name`, `pet_name`, `species`, `kind` (`stage`, `legendary`, `egg` or `level`), plus `stage` or `pet_level` where relevant. It also shows up as **Pet grew up** on the child's [event entity](Event-Entities.md).
+
+Growth is checked once a minute, so a pet grows up within a minute of the chore that did it.
+
+---
+
+## Services
+
+| Service | Fields | Description |
+|---------|--------|-------------|
+| `taskmate.adopt_pet` | `child_id`, `species` (`dragon`, `cat`, `dog`, `bunny`, `dino`, `unicorn`), `name` (up to 24 characters), `hatch_egg` (optional) | Adopt a pet, or rename/re-choose the current one (growth is kept). With `hatch_egg: true`, hatch the egg the grown pet laid; the old pet joins the pet family |
+
+While pets are on, each child's entry in `sensor.taskmate_overview`'s `children` attribute carries a `pet` object (stage, mood, growth, accessories, the next goal, and anything reached after fully grown).
+
+---
+
+## Related
+
+- [Levels and XP](Levels-and-XP.md) — the child levels that unlock accessories
+- [Dashboard Cards](Dashboard-Cards.md) — every TaskMate card
+- [Notifications](Notifications.md) — switching on the Pet grew up notification
+- [Weekly Goals](Weekly-Goals.md) — another motivator for the week
+- [Event Entities](Event-Entities.md) — automating on a pet growing up
diff --git a/wiki/Visibility-Configuration-Guide.md b/wiki/Visibility-Configuration-Guide.md
new file mode 100644
index 00000000..828ae988
--- /dev/null
+++ b/wiki/Visibility-Configuration-Guide.md
@@ -0,0 +1,547 @@
+# Visibility Configuration Guide
+
+Dynamic visibility lets a chore show or hide itself based on the state of any
+Home Assistant entity. This guide walks through configuring it end to end.
+
+
+
+## Quick Start
+
+### Step-by-Step Setup
+
+1. **Open the TaskMate panel**
+ - Click **TaskMate** in the Home Assistant sidebar
+
+2. **Go to Chores**
+ - Either **+ Add chore** to create one, or click the **✏** button on an
+ existing chore's row to edit it
+
+3. **Open the visibility settings**
+ - In the chore dialog, expand **Advanced — visibility & calendar publishing**
+ - Set the three visibility fields (see below)
+
+4. **Save**
+ - Save the chore; the change takes effect on the next refresh
+
+5. **Test**
+ - Open a child card
+ - Verify the chore appears and disappears as the entity changes
+
+> Older versions of TaskMate configured chores through
+> **Settings → Devices & Services → TaskMate → Configure**. That wizard is gone —
+> everything is managed from the TaskMate panel now.
+
+---
+
+## Visibility Fields Explained
+
+### Field 1: Show When Entity Is (optional)
+
+**What it does:** Specifies which Home Assistant entity controls the chore's visibility.
+
+**Examples of valid entity IDs:**
+- `binary_sensor.dishwasher`
+- `sensor.soil_moisture`
+- `input_boolean.guest_mode`
+- `switch.laundry_room`
+- `sensor.outdoor_temperature`
+- `number.threshold_value`
+
+**How to find your entity ID:**
+1. Go to **Developer Tools > States**
+2. Search for the entity you want
+3. Copy the entity ID from the left column
+4. Paste into the visibility field
+
+**Leaving it blank:** If you leave this field empty, visibility filtering is disabled and the chore always shows. Setting the operator to **None** has the same effect, and is what a chore starts with.
+
+---
+
+### Field 2: How to Compare
+
+**What it does:** Specifies the comparison operator to use.
+
+**Available operators:**
+
+| Operator | Best For | Example |
+|----------|----------|---------|
+| `None` | **The default.** No visibility check — the chore always shows | — |
+| `Equals` | String matching | `binary_sensor.door` = `open` |
+| `Not Equal` | Inverse conditions | `input_boolean.guest_mode` ≠ `on` |
+| `≥` (Greater or equal) | Minimum numeric threshold | `sensor.battery` ≥ `80` |
+| `≤` (Less or equal) | Maximum numeric threshold | `sensor.moisture` ≤ `30` |
+| `>` (Greater than) | Above numeric threshold | `sensor.temp` > `20` |
+| `<` (Less than) | Below numeric threshold | `sensor.temp` < `0` |
+
+**How to choose:**
+- **Text values** (`on`, `off`, `home`, `running`): Use `Equals` or `Not Equal`
+- **Numbers** (percentages, temperature, counts): Use `≥`, `≤`, `>`, or `<`
+- **Inverted logic** (show when NOT condition): Use `Not Equal`
+
+---
+
+### Field 3: Value to Compare
+
+**What it does:** Specifies the target value for the comparison.
+
+**For text operators (Equals, Not Equal):**
+- Enter any string value
+- Examples: `on`, `off`, `home`, `away`, `running`, `idle`
+- Must match the entity state exactly (case-insensitive)
+
+**For numeric operators (≥, ≤, >, <):**
+- Enter a number only
+- Decimal values allowed: `22.5`, `10.25`
+- No units: use `30` not `30%` or `30°C`
+
+**Finding the correct value:**
+1. Go to **Developer Tools > States**
+2. Find your entity
+3. Look at the "state" column
+4. Copy the exact value
+
+**Examples:**
+
+```
+Entity: binary_sensor.dishwasher
+State in Developer Tools: "on"
+Value to Compare: on
+
+Entity: sensor.temperature
+State in Developer Tools: 22.5
+Value to Compare: 22.5
+
+Entity: sensor.battery_percent
+State in Developer Tools: 85
+Value to Compare: 80 (if you want >= 80%)
+```
+
+---
+
+## Configuration Workflow
+
+### Scenario 1: Equipment-Based Chores (Binary Sensor)
+
+**Goal:** Show "Fold Laundry" only when the dryer is running.
+
+**Setup:**
+
+1. **Create/Edit Chore**
+ - Name: "Fold Laundry"
+ - Points: 10
+ - Time Category: Anytime
+ - Expand **Advanced — visibility & calendar publishing**
+
+2. **Set Visibility**
+ - **Show When Entity Is:** `binary_sensor.dryer`
+ - **How to Compare:** `Equals`
+ - **Value to Compare:** `on`
+
+3. **Result**
+ - ✅ Shows when dryer IS running (`on`)
+ - ❌ Hides when dryer is off (`off`)
+
+**Why this works:** Children can't fold laundry if it's not done drying yet.
+
+---
+
+### Scenario 2: Sensor-Based Chores (Numeric Threshold)
+
+**Goal:** Show "Water Plants" when soil moisture drops below 40%.
+
+**Setup:**
+
+1. **Create/Edit Chore**
+ - Name: "Water Plants"
+ - Points: 5
+ - Time Category: Morning
+ - Expand **Advanced — visibility & calendar publishing**
+
+2. **Set Visibility**
+ - **Show When Entity Is:** `sensor.soil_moisture`
+ - **How to Compare:** `≤` (Less than or equal)
+ - **Value to Compare:** `40`
+
+3. **Result**
+ - ✅ Shows when moisture is 40% or lower
+ - ❌ Hides when moisture is above 40%
+
+**Why this works:** No need to water if the plant is already moist enough.
+
+---
+
+### Scenario 3: Conditional Chores (Input Boolean)
+
+**Goal:** Show "Lunch Prep" only on school days using an `input_boolean`.
+
+**Setup:**
+
+1. **Create the Helper** (in Settings → Devices & Services → Helpers)
+ - Name: "School Day"
+ - Entity ID: `input_boolean.school_day`
+ - Create automation or manually toggle it
+
+2. **Create/Edit Chore**
+ - Name: "Lunch Prep"
+ - Points: 3
+ - Time Category: Morning
+ - Expand **Advanced — visibility & calendar publishing**
+
+3. **Set Visibility**
+ - **Show When Entity Is:** `input_boolean.school_day`
+ - **How to Compare:** `Equals`
+ - **Value to Compare:** `on`
+
+4. **Result**
+ - ✅ Shows when `input_boolean.school_day` is `on`
+ - ❌ Hides when it's `off`
+
+**Why this works:** Parents can toggle the helper to control when lunch prep shows.
+
+---
+
+### Scenario 4: Inverse Logic (Not Condition)
+
+**Goal:** Show "Tidy Room" only when guests are NOT coming.
+
+**Setup:**
+
+1. **Create/Edit Chore**
+ - Name: "Tidy Room"
+ - Points: 8
+ - Time Category: Anytime
+ - Expand **Advanced — visibility & calendar publishing**
+
+2. **Set Visibility**
+ - **Show When Entity Is:** `input_boolean.guest_mode`
+ - **How to Compare:** `Not Equal`
+ - **Value to Compare:** `on`
+
+3. **Result**
+ - ✅ Shows when guest_mode is OFF (not "on")
+ - ❌ Hides when guest_mode is ON ("on")
+
+**Why this works:** Kids can relax when guests aren't coming; when they are, they should clean instead.
+
+---
+
+### Scenario 5: Temperature-Based Chores
+
+**Goal:** Show "Yard Work" only when it's warm (≥ 20°C).
+
+**Setup:**
+
+1. **Create/Edit Chore**
+ - Name: "Yard Work"
+ - Points: 15
+ - Time Category: Afternoon
+ - Expand **Advanced — visibility & calendar publishing**
+
+2. **Set Visibility**
+ - **Show When Entity Is:** `sensor.outdoor_temperature`
+ - **How to Compare:** `≥` (Greater or equal)
+ - **Value to Compare:** `20`
+
+3. **Result**
+ - ✅ Shows when temperature is 20°C or warmer
+ - ❌ Hides when it's colder than 20°C
+
+**Why this works:** Outdoor work is only reasonable in decent weather.
+
+---
+
+## Verifying Your Configuration
+
+### Check Entity Availability
+
+1. Go to **Developer Tools > States**
+2. Search for your visibility entity
+3. Confirm it exists and has a current state
+4. If it shows "unavailable" or "unknown", fix the integration first
+
+### Test the Condition
+
+Manually toggle or change the entity state in Developer Tools and watch the child card:
+
+1. **Developer Tools > States**
+2. Find your visibility entity
+3. Click the entity row to expand it
+4. Click the "SET STATE" button (if available)
+5. Change to a state that should match your condition
+6. Watch the child card (updates within 30 seconds)
+7. Change back to a state that shouldn't match
+8. Verify the chore hides
+
+### Review Developer Tools > States
+
+After setting up visibility, your entity should appear with the correct state:
+
+```
+binary_sensor.dishwasher: on
+sensor.soil_moisture: 35
+input_boolean.guest_mode: off
+sensor.temperature: 22.5
+```
+
+---
+
+## Numeric Comparison Tips
+
+### Converting Units to Numbers
+
+**Battery percentage example:**
+- Entity: `sensor.battery_percent`
+- State: `85`
+- To show when ≥ 80%: Enter `80`
+
+**Temperature example:**
+- Entity: `sensor.temperature` (in Celsius)
+- State: `22.5`
+- To show when ≥ 20°C: Enter `20`
+
+**Humidity example:**
+- Entity: `sensor.humidity`
+- State: `60`
+- To show when ≤ 70%: Enter `70`
+
+### Decimal Values
+
+Decimal values are fully supported:
+
+```
+Entity: sensor.temperature
+Operator: >
+Value: 20.5
+→ Shows when temperature is above 20.5°C
+```
+
+### Negative Numbers
+
+Negative comparisons work fine:
+
+```
+Entity: sensor.temperature
+Operator: <
+Value: 0
+→ Shows when temperature is below freezing (< 0°C)
+```
+
+---
+
+## Common Configuration Mistakes
+
+### ❌ Mistake 1: Wrong Entity ID
+
+**Problem:** Typo in entity ID
+```
+Configured: binary_sensro.dishwasher (typo)
+Should be: binary_sensor.dishwasher
+```
+
+**Fix:**
+1. Go to Developer Tools > States
+2. Copy the exact entity ID
+3. Paste it correctly
+
+---
+
+### ❌ Mistake 2: Using Units in Numeric Field
+
+**Problem:** Entering units with the number
+```
+Configured: 30% (wrong)
+Should be: 30
+```
+
+**Fix:** Enter only the number, no `%`, `°C`, or other units.
+
+---
+
+### ❌ Mistake 3: Case-Sensitive Matching
+
+**Problem:** Assuming case matters
+```
+Entity state: "Home"
+Configured value: "home" (different case)
+```
+
+**Fix:** Matching is case-insensitive, so both work fine.
+
+---
+
+### ❌ Mistake 4: Guessing the State Value
+
+**Problem:** Assuming a state that the entity never reports
+```
+Guessed: "running"
+Actual state: "active"
+```
+
+**Fix:** Check Developer Tools → States for the value the entity actually
+reports. Case does not matter — `Running` and `running` both match — but the
+word itself has to be right.
+
+---
+
+### ❌ Mistake 5: Using Comparison Operator for Text
+
+**Problem:** Using `>` for text matching
+```
+Operator: > (Greater than)
+State: "running"
+```
+
+**Fix:** Use `Equals` for text values.
+
+---
+
+## Advanced Configurations
+
+### Multiple Chores with Same Condition
+
+Create several chores that share the same visibility condition:
+
+```
+Chores related to dishwasher (all visible when binary_sensor.dishwasher = on):
+1. Load Dishwasher
+2. Unload Dishwasher
+3. Wipe Counters
+```
+
+Each chore can have the same visibility settings.
+
+### Chained Dependencies
+
+Use multiple input_booleans to create complex logic:
+
+```yaml
+# In Home Assistant automation
+- alias: Update chore conditions
+ triggers:
+ - platform: state
+ entity_id: input_boolean.guests_arriving
+ actions:
+ - service: input_boolean.turn_on
+ target:
+ entity_id: input_boolean.room_cleaning_chores
+```
+
+Then set chore visibility to the dependent helper.
+
+### Scheduled Conditions
+
+Create time-based conditions using template sensors:
+
+```yaml
+template:
+ - sensor:
+ - name: "Is School Day"
+ unique_id: is_school_day
+ state: >
+ {% if now().weekday() < 5 %}
+ on
+ {% else %}
+ off
+ {% endif %}
+```
+
+Use `sensor.is_school_day` for visibility.
+
+---
+
+## Troubleshooting Guide
+
+### Chore never appears
+
+**Checklist:**
+1. ✓ Entity ID is correct (check Developer Tools > States)
+2. ✓ Entity state is available (not "unavailable")
+3. ✓ Comparison operator matches your intent
+4. ✓ Value matches the entity state exactly
+5. ✓ Waited 30 seconds for update cycle
+6. ✓ Reloaded the child card (refresh browser)
+
+**How to debug:**
+```
+Go to Developer Tools > States
+Find your visibility entity
+Check the current state value
+Manually verify it should match your condition
+If not, the condition is set incorrectly
+```
+
+---
+
+### Chore always shows
+
+**Checklist:**
+1. ✓ Visibility Entity field is NOT empty
+2. ✓ Visibility State value is correct
+3. ✓ Entity actually exists in Home Assistant
+4. ✓ Entity is not in "unavailable" state
+
+**Note:** If the entity **does not exist at all** (deleted, renamed, or a typo in
+the entity id) the chore defaults to **visible**, so a broken reference can never
+silently hide a family's chores.
+
+An entity that exists but reports `unavailable` or `unknown` is different: that
+is just a state string, and it is compared like any other. It will not match
+`on`, so the chore **hides**. If an integration dropping offline should not hide
+a chore, point the condition at something more stable — or use `Not Equal` so an
+unexpected state leaves the chore showing.
+
+---
+
+### Numeric comparison not working
+
+**Checklist:**
+1. ✓ Entity state is numeric (no text/units)
+2. ✓ Using correct comparison operator (≥, ≤, >, <)
+3. ✓ Value is a valid number (not `30%` or `30°C`)
+4. ✓ Check exact value in Developer Tools > States
+
+---
+
+## Two Behaviours Worth Knowing
+
+### The value field can carry its own operator
+
+If the **Value to Compare** field starts with `>=`, `<=`, `>`, `<` or `!=`, that
+prefix is used as the operator and **overrides the dropdown**. Setting the
+operator to `Equals` and typing `>=50` into the value gives you `≥ 50`, not a
+string match on the literal text `>=50`.
+
+| Value typed | Behaves as |
+|-------------|-----------|
+| `>=10` | Operator `≥`, threshold `10` |
+| `<20` | Operator `<`, threshold `20` |
+| `!=off` | Operator `Not Equal`, value `off` |
+
+This is handy for quick edits, and a trap if you did not expect it.
+
+### Attributes are matched too, not just the state
+
+If the entity's **state** does not match, TaskMate then checks **every attribute
+value** on that entity for a match. So a condition of `home` will also match an
+entity whose state is something else but which carries an attribute equal to
+`home`.
+
+That makes some conditions work that otherwise look like they shouldn't — and it
+can also cause a surprise match. If you need a strict test, pick an entity whose
+state alone carries the meaning.
+
+
+## Getting Help
+
+- [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) — Feature overview
+- [Visibility Operators Reference](Visibility-Operators-Reference.md) — Detailed operator guide
+- [Home Assistant Developer Tools](https://www.home-assistant.io/docs/tools/dev-tools/) — Finding entities
+- [TaskMate GitHub Issues](https://github.com/tempus2016/taskmate/issues) — Report bugs
+
+---
+
+## See Also
+
+- [Getting Started](Getting-Started.md) — full TaskMate setup
+- [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) — Feature overview
+- [Visibility Operators Reference](Visibility-Operators-Reference.md) — Operator details
diff --git a/wiki/Visibility-Operators-Reference.md b/wiki/Visibility-Operators-Reference.md
new file mode 100644
index 00000000..d7c48ded
--- /dev/null
+++ b/wiki/Visibility-Operators-Reference.md
@@ -0,0 +1,470 @@
+# Visibility Operators Reference
+
+## Quick Reference
+
+| Operator | Symbol | Use Case | Example |
+|----------|--------|----------|---------|
+| **None** | — | **The default.** No visibility check — the chore always shows | — |
+| **Equals** | `=` | Exact text match | Entity: `binary_sensor.door`, State: `open` |
+| **Not Equal** | `≠` | Inverted match | Entity: `input_boolean.guest_mode`, State: `on` |
+| **Greater or Equal** | `≥` | Numeric threshold (at or above) | Entity: `sensor.battery`, State: `80` |
+| **Less or Equal** | `≤` | Numeric threshold (at or below) | Entity: `sensor.moisture`, State: `30` |
+| **Greater Than** | `>` | Numeric threshold (above) | Entity: `sensor.temp`, State: `25` |
+| **Less Than** | `<` | Numeric threshold (below) | Entity: `sensor.temp`, State: `0` |
+
+---
+
+## Detailed Operator Guide
+
+### Equals (`=`)
+
+**Description:** Show the chore when the entity state exactly matches the target value (case-insensitive).
+
+**Best For:**
+- Binary states: `on`, `off`
+- Location states: `home`, `away`, `work`
+- Custom string values: `running`, `idle`, `locked`
+- Friendly name states
+
+**Examples:**
+
+```
+Entity: binary_sensor.dishwasher
+Operator: Equals
+State: on
+→ Shows when dishwasher IS running
+```
+
+```
+Entity: person.john
+Operator: Equals
+State: home
+→ Shows when John IS home
+```
+
+```
+Entity: cover.garage_door
+Operator: Equals
+State: open
+→ Shows when garage door IS open
+```
+
+**Technical Details:**
+- Matching is case-insensitive (`On` matches `on`, `HOME` matches `home`)
+- Whitespace is trimmed
+- Works with any string state value
+
+---
+
+### Not Equal (`≠`)
+
+**Description:** Show the chore when the entity state does NOT match the target value (inverse of Equals).
+
+**Best For:**
+- Hiding chores under certain conditions
+- Conditional availability: "show unless..."
+- Input booleans for feature gates
+
+**Examples:**
+
+```
+Entity: input_boolean.guest_mode
+Operator: Not Equal
+State: on
+→ Shows when guests are NOT visiting
+```
+
+```
+Entity: person.parent
+Operator: Not Equal
+State: away
+→ Shows when at least one parent is NOT away
+```
+
+```
+Entity: binary_sensor.school_open
+Operator: Not Equal
+State: on
+→ Shows when school is NOT in session
+```
+
+**Technical Details:**
+- Inverted logic of Equals
+- Also case-insensitive
+- Useful for permission/restriction patterns
+
+---
+
+### Greater Than or Equal (`≥`)
+
+**Description:** Show the chore when the entity state value is greater than or equal to the target number.
+
+**Best For:**
+- Minimum thresholds
+- "At least" conditions
+- Battery levels, stock quantities, percentages
+
+**Examples:**
+
+```
+Entity: sensor.battery_percent
+Operator: ≥
+State: 80
+→ Shows when battery is 80% or higher
+```
+
+```
+Entity: sensor.outdoor_temp
+Operator: ≥
+State: 20
+→ Shows when temperature is 20°C or warmer
+```
+
+```
+Entity: sensor.available_disk_space
+Operator: ≥
+State: 5
+→ Shows when at least 5GB free (if sensor provides GB values)
+```
+
+**Technical Details:**
+- Both values are converted to numbers for comparison
+- Decimal values supported: `22.5`, `10.25`
+- If entity state can't be converted to a number, falls back to string matching
+
+---
+
+### Less Than or Equal (`≤`)
+
+**Description:** Show the chore when the entity state value is less than or equal to the target number.
+
+**Best For:**
+- Maximum thresholds
+- "No more than" conditions
+- Moisture levels, humidity, cost limits
+
+**Examples:**
+
+```
+Entity: sensor.soil_moisture_percent
+Operator: ≤
+State: 30
+→ Shows when soil is 30% moist or drier
+```
+
+```
+Entity: sensor.indoor_humidity
+Operator: ≤
+State: 60
+→ Shows when humidity is 60% or lower
+```
+
+```
+Entity: number.temperature_threshold
+Operator: ≤
+State: 15
+→ Shows when threshold is set to 15°C or lower
+```
+
+**Technical Details:**
+- Converts both values to numbers
+- Decimal values supported
+- Common for sensor-based automation
+
+---
+
+### Greater Than (`>`)
+
+**Description:** Show the chore when the entity state value is strictly greater than (not equal to) the target number.
+
+**Best For:**
+- Exclusive minimum thresholds
+- "More than" conditions
+- Situations where the threshold value itself should hide the chore
+
+**Examples:**
+
+```
+Entity: sensor.outdoor_temp
+Operator: >
+State: 20
+→ Shows when temperature is ABOVE 20°C (20° itself doesn't show)
+```
+
+```
+Entity: counter.days_since_cleaning
+Operator: >
+State: 7
+→ Shows when MORE than 7 days have passed
+```
+
+```
+Entity: sensor.room_occupancy_count
+Operator: >
+State: 0
+→ Shows when room has more than 0 people (i.e., at least 1)
+```
+
+**Technical Details:**
+- Stricter than `≥` (excludes the boundary value)
+- Useful when the exact threshold value has special meaning
+- Numeric conversion with decimal support
+
+---
+
+### Less Than (`<`)
+
+**Description:** Show the chore when the entity state value is strictly less than (not equal to) the target number.
+
+**Best For:**
+- Exclusive maximum thresholds
+- "Less than" conditions
+- Situations where the threshold value itself should hide the chore
+
+**Examples:**
+
+```
+Entity: sensor.outdoor_temp
+Operator: <
+State: 0
+→ Shows when temperature is BELOW 0°C (freezing point)
+```
+
+```
+Entity: sensor.snow_depth_cm
+Operator: <
+State: 5
+→ Shows when snow is less than 5cm deep
+```
+
+```
+Entity: sensor.water_level_percent
+Operator: <
+State: 25
+→ Shows when water level is BELOW 25%
+```
+
+**Technical Details:**
+- Stricter than `≤` (excludes the boundary value)
+- Useful for critical thresholds
+- Numeric conversion with decimal support
+
+---
+
+## Comparison Matrix
+
+| Entity State | ≥ 50 | > 50 | ≤ 50 | < 50 | = 50 | ≠ 50 |
+|--------------|------|------|------|------|------|------|
+| 30 | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ |
+| 50 | ✅ | ❌ | ✅ | ❌ | ✅ | ❌ |
+| 70 | ✅ | ✅ | ❌ | ❌ | ❌ | ✅ |
+
+---
+
+## Real-World Examples
+
+### Example 1: Dishwasher Chores
+
+```
+Chore: "Load Dishwasher"
+Entity: binary_sensor.dishwasher
+Operator: Equals
+State: off
+→ Shows when dishwasher is NOT running (i.e., ready to load)
+```
+
+**Why this works:** When the dishwasher is off, children can load it. When it's running, the chore isn't helpful.
+
+---
+
+### Example 2: Temperature-Based Outdoor Chores
+
+```
+Chore: "Rake Leaves"
+Entity: sensor.outdoor_temperature
+Operator: ≥
+State: 15
+→ Shows when temperature is 15°C or warmer
+```
+
+**Why this works:** You only want kids doing outdoor work in reasonable weather.
+
+---
+
+### Example 3: Watering Plants
+
+```
+Chore: "Water Plants"
+Entity: sensor.soil_moisture
+Operator: ≤
+State: 40
+→ Shows when soil moisture is 40% or lower
+```
+
+**Why this works:** No need to water if the soil is already moist.
+
+---
+
+### Example 4: Guest Mode
+
+```
+Chore: "Clean Room"
+Entity: input_boolean.guests_arriving_today
+Operator: Equals
+State: on
+→ Shows when guests are expected
+```
+
+**Why this works:** You want kids cleaning their rooms when guests are coming.
+
+---
+
+### Example 5: School Day Chores
+
+```
+Chore: "Lunch Prep"
+Entity: input_boolean.school_day
+Operator: Equals
+State: on
+→ Shows only on school days
+```
+
+**Why this works:** Lunch prep is only relevant on days when someone is going to school.
+
+---
+
+## Numeric Conversion Rules
+
+When using comparison operators (`≥`, `≤`, `>`, `<`), TaskMate converts state values to numbers:
+
+### Valid Conversions
+- `"22"` → `22`
+- `"22.5"` → `22.5`
+- `"100%"` → Fails (% breaks conversion, falls back to string)
+- `"-5"` → `-5` (negative numbers work)
+
+### Invalid Conversions (Falls Back to String Matching)
+- `"on"`, `"off"` → Can't convert to number
+- `"running"`, `"idle"` → Can't convert to number
+- `"22.5.1"` → Multiple decimals, can't convert
+
+**When conversion fails:**
+- Operator comparison is skipped
+- Falls back to checking if state equals the target string (case-insensitive)
+- Useful safety net for mixed string/number states
+
+---
+
+## Embedded Operator Shorthand
+
+You can embed the operator directly in the **State** field instead of selecting a separate operator. This is useful for quick configuration or automations:
+
+| State field | Equivalent to |
+|-------------|---------------|
+| `>=10` | Operator: `≥`, State: `10` |
+| `<=30` | Operator: `≤`, State: `30` |
+| `>25` | Operator: `>`, State: `25` |
+| `<0` | Operator: `<`, State: `0` |
+| `!=off` | Operator: `≠`, State: `off` |
+
+When an embedded operator is detected, it **overrides** the selected operator dropdown. This means if you set Operator to `Equals` but the State field contains `>=50`, the chore will use `≥ 50`.
+
+---
+
+## Tips & Tricks
+
+### Tip 1: Combine with Input Booleans
+
+Create custom `input_boolean` helpers for complex logic:
+
+```yaml
+# In configuration.yaml
+input_boolean:
+ chore_day_weekend:
+ name: Chore Day - Weekend
+ chore_day_schoolday:
+ name: Chore Day - School Day
+```
+
+Then use them for visibility:
+```
+Chore: "Yard Work"
+Entity: input_boolean.chore_day_weekend
+Operator: Equals
+State: on
+```
+
+### Tip 2: Use Template Sensors
+
+Create template sensors that calculate conditions:
+
+```yaml
+template:
+ - sensor:
+ - name: "Is Cold"
+ unique_id: sensor_is_cold
+ state: "{{ states('sensor.temperature') | float(0) < 10 }}"
+```
+
+Then use in visibility:
+```
+Entity: sensor.is_cold
+Operator: Equals
+State: "true"
+```
+
+### Tip 3: Test in Developer Tools
+
+Before setting up visibility, verify your entity state:
+
+1. Go to **Developer Tools > States**
+2. Search for your entity
+3. Check the exact state value
+4. Use that value in Visibility State field
+
+### Tip 4: Chain Multiple Conditions
+
+While single conditions are supported, you can simulate AND/OR by:
+- Creating helper automations that update input_booleans
+- Using template sensors to combine multiple entity states
+- Setting up multiple chores with complementary visibility rules
+
+---
+
+## Troubleshooting
+
+### "Entity not found"
+- Check the entity ID spelling in Developer Tools > States
+- Ensure the integration providing the entity is installed and running
+- Wait for Home Assistant to fully load all integrations
+
+### "Numeric comparison not working"
+- Verify the entity state is actually numeric (no units or symbols)
+- Check Developer Tools > States for the exact value
+- Try converting to string comparison if state has units
+
+### "Chore shows even when condition isn't met"
+- Double-check the Visibility State value matches exactly
+- For numeric operators, ensure the number is valid
+- Wait 30 seconds for the visibility update cycle
+- Reload the TaskMate integration
+
+---
+
+## Attributes Are Matched Too
+
+If the entity's **state** does not match, TaskMate then checks **every attribute
+value** on that entity for a match. A condition of `home` will therefore also
+match an entity whose state is something else but which carries an attribute
+equal to `home`.
+
+This makes some conditions work that otherwise look like they shouldn't — and it
+can also produce a surprise match. If you need a strict test, choose an entity
+whose state alone carries the meaning.
+
+---
+
+## See Also
+
+- [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) — Feature overview and setup
+- [Getting Started](Getting-Started.md) — complete TaskMate setup
diff --git a/wiki/Voice-Assistants.md b/wiki/Voice-Assistants.md
new file mode 100644
index 00000000..8d0b22df
--- /dev/null
+++ b/wiki/Voice-Assistants.md
@@ -0,0 +1,133 @@
+# Voice Assistants
+
+TaskMate adds Home Assistant **conversation intents** so you can ask Assist — by voice or text — about your children's chores and points, and tick chores off.
+
+- *"How many chores does Malia have left?"*
+- *"How many stars does Alex have?"*
+- *"Mark make bed as done for Malia"* (v7.0.0)
+- *"What's Malia's next job?"* (v7.0.0)
+- *"How close is Alex to the cinema trip?"* (v7.0.0)
+
+---
+
+## How It Works
+
+There are two halves to a voice command in Home Assistant:
+
+1. **The intent handler** — the code that answers the question. TaskMate ships five intent handlers and registers them automatically when the integration loads. Nothing to install.
+2. **The trigger sentences** — the phrases HA listens for and maps to an intent. These are **not** automatic. HA's default conversation agent loads them from your config folder, so you have to copy TaskMate's example sentences in once.
+
+The intents TaskMate provides:
+
+| Intent | Answers or does | Example |
+|--------|-----------------|---------|
+| `TaskMateChoresLeft` | How many chores are still to do today | "How many chores does **Malia** have left?" |
+| `TaskMatePoints` | The child's points balance | "How many stars does **Alex** have?" |
+| `TaskMateCompleteChore` | *(v7.0.0)* Ticks a chore off for the child | "Mark **make bed** as done for **Malia**" |
+| `TaskMateNextChore` | *(v7.0.0)* The chore the child should do next | "What's **Malia**'s next job?" |
+| `TaskMateRewardProgress` | *(v7.0.0)* How many more points the child needs for a reward | "How close is **Alex** to the **cinema trip**?" |
+
+The slots in the sentences:
+
+| Slot | Matches |
+|------|---------|
+| `{child}` | Any of your children by name (case-insensitive) |
+| `{chore}` | A chore due today. The closest name wins: an exact match first, then one containing what was said, then the most words in common |
+| `{reward}` | A reward the child can claim, matched the same way. Leave it out ("how close is Alex to a reward") and TaskMate picks the cheapest reward the child can't afford yet |
+
+### Completing a chore by voice
+
+`TaskMateCompleteChore` counts as the child's own tap, never a parent's:
+
+- Approval rules apply exactly as if the child had tapped **Done**. A chore that needs approval goes to the queue ("Done! Make bed is waiting for a grown-up to check it").
+- The [linked-account rules](Parent-Access.md) decide whether the person speaking may act for that child. If not, Assist says so and nothing is completed.
+- Chores that need a photo, a number ([quantity chores](Quantity-Chores.md)), a description, a timer or a team can't be finished by voice. Assist says to do that one on the card.
+- A chore already done today is reported as done rather than completed again.
+
+### Replies in your language
+
+Replies are translated. Assist answers in the language the question was asked in, using the same translations as TaskMate's push notifications, so a German question gets a German answer.
+
+---
+
+## Installing the Trigger Sentences
+
+Example sentences ship in the TaskMate repository under `custom_sentences//taskmate.yaml`, for these languages:
+
+| Code | Language |
+|------|----------|
+| `en` | English |
+| `da` | Danish |
+| `de` | German |
+| `fr` | French |
+| `nb` | Norwegian Bokmål |
+| `nn` | Norwegian Nynorsk |
+| `pl` | Polish |
+| `pt` | Portuguese |
+| `pt-BR` | Portuguese (Brazil) |
+
+Copy the file for your language into your Home Assistant config, keeping the same path. For English:
+
+```
+/custom_sentences/en/taskmate.yaml
+```
+
+Then **restart Home Assistant** (or reload the conversation integration). After that, ask Assist any of the sentences above and TaskMate will answer.
+
+> **Upgrading from before v7.0.0?** Copy the file again. Older copies used `{name}` for the child's name, but Home Assistant reserves `{name}` for device and entity names, so a sentence using it could be answered with "not aware of any device called …" instead of reaching TaskMate. The new files use `{child}` and add the three new intents. If you wrote your own sentences, change `{name}` to `{child}` in them, and rename the `name:` entry under `lists:` to `child:`. TaskMate still accepts `{name}` from an old file, so nothing breaks in the meantime.
+
+A minimal English file looks like this:
+
+```yaml
+language: "en"
+intents:
+ TaskMateChoresLeft:
+ data:
+ - sentences:
+ - "how many chores (does|has) {child} have left"
+ TaskMateCompleteChore:
+ data:
+ - sentences:
+ - "mark {chore} [as] done for {child}"
+ TaskMateNextChore:
+ data:
+ - sentences:
+ - "what('s| is) {child}'s next (job|chore)"
+ TaskMateRewardProgress:
+ data:
+ - sentences:
+ - "how close is {child} to [the] {reward}"
+lists:
+ child:
+ wildcard: true
+ chore:
+ wildcard: true
+ reward:
+ wildcard: true
+```
+
+---
+
+## Other Languages
+
+For a language not in the list, copy one of the files under the matching language code, for example:
+
+```
+/custom_sentences/es/taskmate.yaml
+```
+
+Then translate **only** the `sentences:` lines into that language. Leave the intent names (`TaskMateChoresLeft`, `TaskMatePoints`, `TaskMateCompleteChore`, `TaskMateNextChore`, `TaskMateRewardProgress`), the slot names (`{child}`, `{chore}`, `{reward}`) and the `lists:` keys unchanged — those are identifiers, not display text. See [Localization](Localization.md) for TaskMate's language support generally.
+
+---
+
+## Voice-Friendly To-do Lists
+
+TaskMate also publishes each child's outstanding chores as a native HA to-do list (`todo.taskmate_`). Because those are standard to-do lists, voice assistants can read them out and tick items off — completing the chore — with no extra setup. This pairs well with the intents above. See [To-Do Lists](To-Do-Lists.md).
+
+---
+
+## See Also
+
+- [To-Do Lists](To-Do-Lists.md) — voice-friendly chore lists per child
+- [Parent Access](Parent-Access.md) — linked accounts, which decide who may complete chores for whom
+- [Localization](Localization.md) — translating TaskMate
diff --git a/wiki/Watch-Complications.md b/wiki/Watch-Complications.md
new file mode 100644
index 00000000..4aee12ed
--- /dev/null
+++ b/wiki/Watch-Complications.md
@@ -0,0 +1,229 @@
+# Watch Complications
+
+Put a child's chores on their wrist. TaskMate gives every child a small **watch sensor** ("3 left", "All done") and a **complete next chore** action, sized for Apple Watch complications and Wear OS complications and tiles. This page has copy-paste templates for both.
+
+
+
+> **New in v6.0.0**
+
+Watch faces aren't built by TaskMate itself. They're set up in the **Home Assistant companion apps**, using the sensor and action below.
+
+---
+
+## The Watch Sensor
+
+Every child gets `sensor.taskmate__watch`, for example `sensor.taskmate_mia_watch`.
+
+### State
+
+A short phrase that fits on a complication, in your Home Assistant server's language:
+
+| State | When |
+|-------|------|
+| `3 left` | Chores still to do today (the number changes) |
+| `All done` | Everything for today is done |
+| `No chores` | Nothing was due today |
+
+### Attributes
+
+| Attribute | Example | Description |
+|-----------|---------|-------------|
+| `child_id` | `34261cf3e2ad40a0` | The child's ID, for the action below |
+| `status` | `to_do` | `to_do`, `all_done` or `no_chores`. The same in every language, so use this in templates rather than the state text. |
+| `left` | `3` | Chores still to do today |
+| `done` | `4` | Chores done today, including ones waiting for approval |
+| `total` | `7` | Chores due today |
+| `progress` | `0.57` | `done / total`, from `0` to `1`. Ready for a gauge or ring. `1.0` when nothing was due. |
+| `points` | `126` | Current points |
+| `streak` | `5` | Current streak in days |
+| `next_chore` | `Make bed` | The chore **complete next chore** would tick off. Only present when there is one. Clipped to 40 characters. |
+
+The counts use the same definition as the **Today** page in the TaskMate panel. `left` includes chores that need a photo or a timer; `next_chore` skips them (see below).
+
+Replace `mia` with your child's name in every template on this page.
+
+---
+
+## The "Complete Next Chore" Action
+
+`taskmate.complete_next_chore` ticks off the child's next outstanding chore. It's made for a watch button.
+
+| Field | Required | Description |
+|-------|----------|-------------|
+| `child_id` | Yes | The child's ID (the `child_id` attribute of their watch sensor) |
+
+- **"Next"** is the order the child sees on their card: their own custom order first, then the default order.
+- **Skipped:** chores a single tap can't finish: [photo proof](Photo-Proof.md), [open-ended](Open-Ended-Chores.md), [timed](Timed-Tasks.md) and [teamwork](Teamwork-Chores.md) chores.
+- **Normal rules apply:** approval, points and notifications behave exactly as if the child had tapped the chore on their card.
+- **Nothing left?** It quietly does nothing, so a button pressed once too often doesn't raise an error.
+- **Linked accounts:** it follows the same rule as ticking a chore. If the child is linked to a Home Assistant user, the watch has to be signed in as that user (or an admin).
+
+### Wrap it in a script
+
+Watches run **scripts**, so create one per child. **Settings → Automations & scenes → Scripts → Add script → Edit in YAML**:
+
+```yaml
+alias: Mia – next chore done
+icon: mdi:check-circle-outline
+mode: single
+sequence:
+ - action: taskmate.complete_next_chore
+ data:
+ child_id: "{{ state_attr('sensor.taskmate_mia_watch', 'child_id') }}"
+```
+
+Reading the ID from the sensor means you never have to look it up.
+
+---
+
+## Apple Watch
+
+You need watchOS 9 or later, and you must be a Home Assistant **admin** to create complications.
+
+### Adding a complication
+
+1. On your iPhone, open the Home Assistant app's settings and go to the **Apple Watch** section → **Complications**.
+2. Add a complication and pick a family and template (see below).
+3. Paste the templates into the text, gauge or ring fields, and save.
+4. On the watch, long-press the watch face → **Edit** → pick the Home Assistant complication.
+
+For the Modular face (watchOS 9 and later), choose **Circular** or **Rectangular** from the **Graphic** section.
+
+**Gauge and ring fields need a number from `0.0` to `1.0`.** That's exactly what the `progress` attribute gives you.
+
+### Inline text
+
+For a one-line complication (such as the text along the top of the face):
+
+```jinja
+{% set w = 'sensor.taskmate_mia_watch' %}
+{% if is_state_attr(w, 'status', 'to_do') %}{{ state_attr(w, 'left') }} left · {{ state_attr(w, 'next_chore') or '' }}{% else %}✓ {{ states(w) }}{% endif %}
+```
+
+Shows `3 left · Make bed`, or `✓ All done`.
+
+For the shortest possible text, just use the state:
+
+```jinja
+{{ states('sensor.taskmate_mia_watch') }}
+```
+
+### Circular gauge or ring
+
+Pick a **Graphic → Circular** template with a gauge or ring.
+
+**Gauge / ring value:**
+
+```jinja
+{{ state_attr('sensor.taskmate_mia_watch', 'progress') | float(0) }}
+```
+
+**Centre text:** how many are left:
+
+```jinja
+{{ state_attr('sensor.taskmate_mia_watch', 'left') | int(0) }}
+```
+
+…or done out of total:
+
+```jinja
+{% set w = 'sensor.taskmate_mia_watch' %}{{ state_attr(w, 'done') | int(0) }}/{{ state_attr(w, 'total') | int(0) }}
+```
+
+The ring fills as the day's chores get done, and is full once everything is ticked off.
+
+### Rectangular
+
+Pick a **Graphic → Rectangular** template. Fill as many lines as the template offers.
+
+**Header:**
+
+```jinja
+Mia's chores
+```
+
+**Line 1:**
+
+```jinja
+{{ states('sensor.taskmate_mia_watch') }}
+```
+
+**Line 2:** the next chore, or the state when there isn't one:
+
+```jinja
+{% set w = 'sensor.taskmate_mia_watch' %}{% set nxt = state_attr(w, 'next_chore') %}{{ ('Next: ' ~ nxt) if nxt else states(w) }}
+```
+
+**Line 3** (or a second text field): points and streak:
+
+```jinja
+{% set w = 'sensor.taskmate_mia_watch' %}⭐ {{ state_attr(w, 'points') | int(0) }} · 🔥 {{ state_attr(w, 'streak') | int(0) }}
+```
+
+**Gauge** (on templates that have one): use the `progress` template above.
+
+### A "done" button on the watch
+
+In the iPhone app's **Apple Watch** section, open **Configuration**, add the *Mia – next chore done* script, then **Save**. Reload the Home Assistant app on the watch. The script now shows as a button in the watch app.
+
+### How often it updates
+
+Apple Watch complications refresh roughly every 15 minutes (around :00, :15, :30 and :45), at a time chosen by watchOS. So a completed chore can take a few minutes to show on the face.
+
+---
+
+## Wear OS
+
+You need the Home Assistant app on the watch, signed in through a paired Android phone.
+
+### Entity State complication
+
+The simplest option, and it needs no template.
+
+1. On the **watch**, long-press the watch face → **Customise** → pick a complication slot.
+2. Choose **Home Assistant → Entity state**.
+3. Pick `sensor.taskmate_mia_watch`.
+
+It shows the sensor's state: `3 left`, `All done` or `No chores`. You can optionally show the entity's name too.
+
+This has to be set up on the watch itself, not in the watch app on the phone. The complication updates when the screen turns on and roughly every 15 minutes, and you can tap it to update it straight away.
+
+### Template tile
+
+A tile with more detail. The template is set from the **Android companion app** on the phone (the Wear OS settings), then the tile is added on the watch.
+
+```jinja
+{% set w = 'sensor.taskmate_mia_watch' %}
+{{ states(w) }}
+{% if state_attr(w, 'next_chore') %}Next: {{ state_attr(w, 'next_chore') }} {% endif %}
+⭐ {{ state_attr(w, 'points') | int(0) }} · 🔥 {{ state_attr(w, 'streak') | int(0) }}
+```
+
+Template tiles understand a few HTML tags: ``, ``, ``, ` ` and ``. Set the tile's **refresh interval** to every few minutes so it keeps up.
+
+### Shortcut
+
+Add the *Mia – next chore done* script as a shortcut:
+
+1. On the **watch**, open the Home Assistant app → **Settings** → the Shortcuts tile.
+2. Add the script. A Shortcuts tile holds up to 7 shortcuts.
+3. Add the Shortcuts tile to your tiles.
+
+One tap on the tile ticks off the next chore. You can also add the script to the app's **Favourites**.
+
+---
+
+## Tips
+
+- **Test your templates first** in Home Assistant's **Developer tools → Template** tab. Paste one in and check the output before putting it on the watch.
+- **Use `status`, not the state text,** in `if` tests. The state is translated, and `status` is not.
+- **A child sharing a parent's phone?** Point the complication at their own watch sensor, and use a separate script per child.
+
+---
+
+## Related
+
+- [Sensor Reference](Sensor-Reference.md) — all TaskMate sensors
+- [Services](Services.md) — full service reference
+- [Voice Assistants](Voice-Assistants.md) — another hands-free way to tick off chores
+- [Children](Children.md) — linking a child to a Home Assistant user
diff --git a/wiki/Weather-Aware-Chores.md b/wiki/Weather-Aware-Chores.md
new file mode 100644
index 00000000..089d6b96
--- /dev/null
+++ b/wiki/Weather-Aware-Chores.md
@@ -0,0 +1,74 @@
+# Weather Aware Chores
+
+Outdoor chores can hide themselves when the weather is unsuitable. There is no point putting "mow the lawn" on a child's card during a downpour, and no point penalising them for not doing it.
+
+
+
+Open a chore in the **Admin Panel → Chores → Edit chore** and expand **Advanced — weather conditions**.
+
+---
+
+## Settings
+
+| Setting | Effect |
+|---------|--------|
+| **Weather entity** | The `weather.*` entity to read. Leave empty to ignore the weather entirely. |
+| **Hide when the weather is** | Any number of conditions — rainy, pouring, snowy, sleet, hail, lightning, thunderstorm, fog, windy, very windy, cloudy, severe. |
+| **Minimum temperature** | Hide the chore below this. Leave empty for no limit. |
+| **Maximum temperature** | Hide the chore above this. Leave empty for no limit. |
+| **Maximum wind speed** | Hide the chore above this. Leave empty for no limit. |
+
+Temperature and wind limits are read from the weather entity's `temperature` and `wind_speed` attributes, in whatever units your entity reports. TaskMate does not convert units — if your weather entity reports °F, enter your limits in °F.
+
+Conditions are checked first, then temperature, then wind.
+
+---
+
+## A Rained-Off Chore Is Not a Missed Chore
+
+The weather check sits in the same availability path as scheduling, rotation and dependencies. That means a chore hidden by the weather:
+
+- does **not** raise a mandatory-miss review item
+- does **not** break the child's streak
+- does **not** count against the chore in the [Insights](Insights.md) friction report
+
+It simply isn't due today, in the same way a Tuesday-only chore isn't due on a Wednesday.
+
+---
+
+## Fail-Open by Design
+
+Anything that goes wrong leaves the chore **visible**:
+
+- the weather entity is missing or was deleted
+- its state is `unavailable` or `unknown`
+- the attribute a limit needs (`temperature`, `wind_speed`) isn't present
+
+A weather integration going offline overnight must never quietly hide the whole family's chores. The failure mode is "the child sees a chore they might not need to do", not "nobody does anything".
+
+---
+
+## 0 Is a Real Limit
+
+Leave a limit **blank** to disable it. Entering `0` means zero degrees, not "off" — a common trap worth stating plainly, because "hide below 0°" and "no minimum" are very different instructions.
+
+---
+
+## Common Use Cases
+
+| Chore | Setting |
+|-------|---------|
+| Mow the lawn | Hide on `rainy` and `pouring` |
+| Wash the car | Hide below 2° |
+| Put the bins out | Hide above 40 km/h wind |
+| Water the plants | Hide on `rainy` — nature did it for you |
+| Sweep the patio | Hide on `snowy`, hide below 0° |
+
+---
+
+## Related
+
+- [Chores](Chores.md) — the chore editor and the full list of chore fields
+- [Dynamic Chore Visibility](Dynamic-Chore-Visibility.md) — gating a chore on any Home Assistant entity state, not just weather
+- [Chore Scheduling](Chore-Scheduling.md) — how a chore becomes due in the first place
+- [Mandatory Chores](Mandatory-Chores.md) — why a weather-hidden chore never raises a miss
diff --git a/wiki/Weekly-Digest.md b/wiki/Weekly-Digest.md
new file mode 100644
index 00000000..72458036
--- /dev/null
+++ b/wiki/Weekly-Digest.md
@@ -0,0 +1,63 @@
+# Weekly Digest
+
+The weekly digest is a Sunday-evening summary sent to parents recapping each child's week. It turns a week of activity into a single at-a-glance message.
+
+
+
+Added in v4.0.0.
+
+---
+
+## What It Contains
+
+The digest lists one line per child showing how many chores they completed and how many points they earned over the week:
+
+```
+TaskMate weekly digest:
+• Alex: 5 chores, 50 Stars earned
+• Mia: 3 chores, 30 Stars earned
+```
+
+Counts are built from **approved** chore completions since the start of the current week (Monday). The points figure is the points awarded by those completions. **Bonus subtask** completions and **pending** (unapproved) completions are excluded, and only the current week is counted. The points label follows your configured points name (e.g. "Stars").
+
+If there are no children, no digest is sent.
+
+---
+
+## Schedule
+
+- The digest fires on **Sundays at 18:00** (local time).
+- Internally a check runs daily at 18:00 and only sends on Sundays — no separate automation is required.
+
+---
+
+## Monthly Report
+
+For a longer-period view, there is now also a **monthly report** (the `monthly_report` notification). It fires on the **1st of each month** at 18:00 and recaps the **previous calendar month** for each child — chores completed, points earned, level and best streak. Like the weekly digest it has the parent audience, is delivered through the standard [notification system](Notifications.md), and is **off by default**. Enable and route the **Monthly report** type on the Notifications tab the same way as the weekly digest.
+
+---
+
+## Audience & Target
+
+The digest has the **parent** audience. It is delivered through the standard [notification system](Notifications.md), so it goes to the parent recipients you have enabled for the **Weekly digest** type in the recipient routing matrix, plus the usual persistent notification in Home Assistant.
+
+---
+
+## Enabling & Configuring
+
+The weekly digest is a built-in notification type (`weekly_digest`) and is **off by default**.
+
+1. Open the **Admin Panel → Notifications** tab.
+2. Enable the **Weekly digest** type's master toggle.
+3. In the recipient routing matrix, enable it for each parent recipient who should receive it.
+
+You can verify routing without waiting for Sunday by using **Send test** on the Weekly digest row (see [Notifications — Testing a Notification](Notifications.md#testing-a-notification)).
+
+The matching `taskmate_weekly_digest` bus event carries the rendered `summary` and the `recipients` list — see [Automations](Automations.md).
+
+---
+
+## Related
+
+- [Notifications](Notifications.md) — the notification system that delivers the digest and monthly report
+- [Admin Panel](Admin-Panel.md) — where to enable and route it
diff --git a/wiki/Weekly-Goals.md b/wiki/Weekly-Goals.md
new file mode 100644
index 00000000..29ebe881
--- /dev/null
+++ b/wiki/Weekly-Goals.md
@@ -0,0 +1,114 @@
+# Weekly Goals
+
+Personal weekly goals let each child pick their own target for the week: "I want to earn 120 points this week." Their card shows how close they are, and reaching the goal pays a bonus once a week. Children who choose their own goal tend to care more about hitting it than one set for them.
+
+
+
+> **New in v7.0.0**
+
+---
+
+## Turning It On
+
+**TaskMate panel → Settings → Personal weekly goals**
+
+
+
+| Setting | Key | Default | Description |
+|---------|-----|---------|-------------|
+| **Let children set a weekly goal** | `weekly_goal_enabled` | off | Shows the goal on every child card and allows goals to be set |
+| **Bonus for reaching it** | `weekly_goal_bonus` | `10` | Points paid once a week when a child reaches their goal. 0 = no bonus, just the satisfaction of hitting it |
+
+The bonus is the same for every child. It's a fixed amount, not a percentage of the goal, so setting a huge goal doesn't pay more.
+
+---
+
+## Setting a Goal
+
+Once goals are on, a child without one sees **Set a goal for this week** on their card ("Pick how many points you want to earn. Reach it for +15!"). Tapping it, or **Change** once a goal is set, opens the goal sheet.
+
+
+
+The sheet tells the child how many points they **could** earn this week from their chores, and offers quick picks at a quarter, half, three quarters and all of that. They can also type a number or use **−** / **+**, then tap **Save goal**.
+
+A goal carries over from week to week until it is changed, so a child who likes their goal doesn't have to set it every Monday. Setting the goal to 0 clears it.
+
+Parents can set or change a goal for a child with the `set_weekly_goal` service.
+
+---
+
+## Progress and the Bonus
+
+The goal widget sits above the chore list: **My goal: 36 / 120 this week**, with a progress bar. It counts the points from chores approved since Monday (bonus sub-tasks aside), the same figure the rest of the card uses for the week.
+
+When the week's points reach the goal:
+
+- the child gets the bonus ("Weekly goal reached 🎯 (120)" in their history), and the widget turns green: **Goal reached! +15 🎉**
+- the *Weekly goal reached* notification goes out, if it's on
+
+The goal is checked once a minute, and again straight away when a goal is saved, so setting a goal you have already passed this week counts at once.
+
+### Once a week
+
+The bonus is paid at most once per child per week (weeks start on Monday). Lowering the goal after reaching it, or clearing it and setting it again, doesn't pay a second bonus that week.
+
+### If points are taken back
+
+If a completion that counted towards the goal is undone, rejected or un-approved, and that drops the week's points below the goal, the bonus is taken back too ("Weekly goal reversed (120)"), along with its share of the leaderboard tally. The goal can then be reached, and paid, again later in the week.
+
+A child's own undo checks that they still have the bonus in hand before letting them undo.
+
+---
+
+## Card Option
+
+The widget appears on the [child card](Dashboard-Cards.md#child-card) in every design while weekly goals are on. To hide it on one card:
+
+```yaml
+type: custom:taskmate-child-card
+entity: sensor.taskmate_overview
+child_id: 8e16ad66b23f404e
+show_weekly_goal: false
+```
+
+In the editor it's **Show my weekly goal**.
+
+---
+
+## Notification
+
+**Weekly goal reached** (off by default; switch it on under **Notifications**): "🎯 Vaiha reached their weekly goal of 120 Points — +15 bonus!" It can go to the child, parents or both.
+
+It fires the `taskmate_weekly_goal_reached` event whether or not the notification is on, with `child_id`, `child_name`, `target`, `earned`, `bonus` and `points_name`. On the child's [event entity](Event-Entities.md) it shows as **Weekly goal reached**.
+
+---
+
+## Service
+
+| Service | Fields | Description |
+|---------|--------|-------------|
+| `taskmate.set_weekly_goal` | `child_id`, `target` (0–100,000) | Set a child's weekly points goal. 0 clears it |
+
+While goals are on, each child's entry in `sensor.taskmate_overview`'s `children` attribute carries `weekly_goal`: `target`, `bonus`, and, once a target is set, `earned` and `reached`.
+
+---
+
+## Weekly Goals or Weekly Targets?
+
+They're different features and can be used together:
+
+| | Weekly goals | [Weekly targets](Weekly-Targets.md) |
+|---|---|---|
+| Set by | The child (or a parent) | A parent, per chore |
+| Measures | Points earned this week | How many times one chore is done this week |
+| Reward | One family-wide bonus per week | A bonus per chore target |
+
+---
+
+## Related
+
+- [Weekly Targets](Weekly-Targets.md) — per-chore weekly counts
+- [Bonus Points](Bonus-Points.md) — streak and perfect-week bonuses
+- [Child Undo Window](Child-Undo-Window.md) — how undo interacts with bonuses
+- [Virtual Pets](Virtual-Pets.md) — another long-running motivator
+- [Notifications](Notifications.md)
diff --git a/wiki/Weekly-Targets.md b/wiki/Weekly-Targets.md
new file mode 100644
index 00000000..403ca2e2
--- /dev/null
+++ b/wiki/Weekly-Targets.md
@@ -0,0 +1,119 @@
+# Weekly Targets
+
+Some chores aren't owed on a particular day — they're owed by the end of the week. Practise the piano three times. Read on four evenings. Get out for a run twice. A **weekly target** says *how many times this week*, and lets the child pick the days.
+
+
+
+> **New in v5.8.0** (#904)
+
+---
+
+## How It Works
+
+Set **Weekly target** on a chore to any number above zero. The chore is then offered on its usual days until the child has done it that many times this week, and stops being offered once the quota is full. The week is **Monday-anchored**, the same as [Challenges](Challenges.md).
+
+Progress shows on the chore's row in the child card from the first tick — `2/3 this week` — and the row dims once the target is met.
+
+The count is worked out from completions every time it's needed, never stored. Nothing has to reset on a Monday, and if you raise the target mid-week the chore simply becomes available again.
+
+---
+
+## Setting a Target
+
+**TaskMate panel → Chores → edit a chore → Weekly target**
+
+| Field | Default | Description |
+|-------|---------|-------------|
+| **Weekly target** | `0` | How many times a week this must be done. `0` = off, the chore behaves exactly as before. |
+| **Weekly target bonus** | `0` | *(v6.2.0)* Extra points paid once the target is reached. `0` = no bonus. See [Weekly Target Bonus](#weekly-target-bonus) below. |
+
+The target is one number, and the bonus is optional. Everything else about the chore stays as it is.
+
+The weekly target fields sit under the day buttons, so they show when the chore's **Schedule mode** is *Specific days*.
+
+---
+
+## Weekly Target Bonus
+
+> **New in v6.2.0**
+
+A weekly target can carry a reward for hitting it. Set **Weekly target bonus** and the child gets those extra points once they reach the target, on top of the normal points for each completion.
+
+
+
+*Example:* **Brush teeth**, weekly target 7, bonus 10. Each brush pays its usual points, and at 7/7 the child gets **+10** once.
+
+### When it's paid
+
+- **On approval.** A pending completion still counts towards the target, but the bonus is only paid once enough completions are **approved** to reach it. On a chore that doesn't need approval, that is the tap that fills the quota. On one that does, it is when you approve the last completion needed.
+- **Once per week.** Each child can earn it once per chore per week (Monday to Sunday).
+- **For the week the work was done.** Approving last Sunday's completion on a Monday settles *last* week's bonus. This week's bonus is still there to earn.
+- [Bonus sub-tasks](Bonus-Subtasks.md) don't count towards the target.
+
+The payment shows in the child's history as its own line, **Weekly target bonus: Brush teeth**. It can't be undone on its own from the panel or the activity card, because that would leave the week marked as paid. Undo or reject the completion instead (see below).
+
+### When it's taken back
+
+If an undone approval, a rejection or a [child undo](Child-Undo-Window.md) drops the week back below the target, the bonus is refunded automatically. It shows as **Weekly target bonus reversed: Brush teeth**. Once the child is back at the target, they can earn it again.
+
+### What the child sees
+
+When a tap on the [child card](Dashboard-Cards.md#child-card) fills the quota on a chore that doesn't need approval, the celebration popup adds a line: **🎉 Weekly target reached! +10**.
+
+### For automations
+
+Reaching the target fires a `taskmate_weekly_target_reached` event (see [Automations](Automations.md#chores)) and a medium (tier 2) [celebration](Celebrations.md) of kind `weekly_target_reached`. If you've turned on celebration notifications, that covers it too.
+
+---
+
+## It Rides On Top Of The Schedule
+
+A weekly target is **not** a scheduling mode. It sits on top of whichever schedule the chore already has, which means you can combine the two:
+
+| Setup | Result |
+|-------|--------|
+| Days: all, target 3 | Three times this week, any day at all |
+| Days: Mon–Fri, target 3 | Three times this week, but only on weekdays |
+| Days: Mon, Wed, Fri, target 2 | Two of those three days — the child picks which |
+
+Leave the target at `0` and nothing changes: the chore is due on every day you chose, as always.
+
+---
+
+## Pending Approvals Count
+
+A completion waiting for your approval counts toward the target straight away. A slow approval never hands out a spare go, and the numbers a child sees always match what they've actually done.
+
+If you **reject** a completion, its slot is freed again — the record is deleted, so the count drops back.
+
+---
+
+## Interaction With Other Features
+
+| Feature | Behaviour |
+|---------|-----------|
+| **Daily limit** | Today's allowance is capped by what's left in the week. A chore with a daily limit of 5 and one tick left in its quota offers one more, not five. |
+| **[Mandatory chores](Mandatory-Chores.md)** | A mandatory chore with a filled quota doesn't raise a nightly miss. It isn't owed today — it's owed by Sunday. |
+| **Perfect weeks** | With *perfect week requires all chores* enabled, a weekly chore isn't counted as "due today". It has the rest of the week to be done. |
+| **[Rotation](Task-Groups.md) / first-come** | Unchanged. The target applies to whoever the chore lands on. |
+
+---
+
+## Good Candidates
+
+- **Instrument practice** — "three times a week", not "every Tuesday"
+- **Reading** — four evenings out of seven
+- **Exercise** — twice a week, whenever it suits
+- **Helping with dinner** — two nights, child's choice
+
+Anything where the requirement is a weekly minimum rather than a particular day.
+
+---
+
+## See Also
+
+- [Chores](Chores.md) — creating and configuring chores
+- [Chore Scheduling](Chore-Scheduling.md) — specific days, recurring, rotation and first-come
+- [Mandatory Chores](Mandatory-Chores.md) — must-do chores with late penalties
+- [Challenges](Challenges.md) — the other Monday-anchored weekly system
+- [Celebrations](Celebrations.md) — the `weekly_target_reached` celebration
diff --git a/wiki/Wishlist.md b/wiki/Wishlist.md
new file mode 100644
index 00000000..8dc43544
--- /dev/null
+++ b/wiki/Wishlist.md
@@ -0,0 +1,123 @@
+# Wishlist
+
+Children keep a list of things they'd love to have and save their points towards them. You approve each wish and set its price, and the rest of the family can chip in: Grandma's 60-point pledge shows up as its own stripe on the progress bar. When a wish is fully funded, the child asks to redeem it and it arrives in your approval queue like any reward claim.
+
+
+
+> **New in v6.0.0**
+
+---
+
+## How It Works
+
+1. **The child adds a wish** on their Wishlist card: a name, a suggested target, and optionally a link and a picture. It waits for a grown-up.
+2. **You approve it** on the **Wishlists** page, changing the target first if you like. Or you decline it, with an optional reason the child will see.
+3. **The child saves towards it** by moving points in. The slider stops at what they can spend and at what the wish still needs.
+4. **Family members pledge** points through you ("Grandma +60").
+5. **Once it's fully funded**, the child taps **Ask to redeem**, and it becomes a normal reward claim for you to approve.
+
+---
+
+## Whose Points Are Whose
+
+| Points | Where they come from | Can they come back out? |
+|--------|----------------------|-------------------------|
+| **Saved** ("Me") | The child's own balance | Yes. The child can **Take back** their own savings at any time |
+| **Pledged** ("Family") | A gift you record on someone's behalf | No. Pledges never come out of a wish and never touch any child's balance |
+
+Saved points leave the child's spendable balance straight away, like a savings jar, but they are still theirs. The card shows both numbers: "You can spend 596 · 160 saved in wishes".
+
+- **Declining or deleting** a wish gives the child back everything they saved and cancels every pledge.
+- **Redeeming** a wish takes nothing more from the wallet, because the saved points already left it.
+- Moving points in and taking them back out doesn't count towards the monthly leaderboard, so it can't be used to farm season points.
+- Every movement (save, take back, pledge, pledge removed, refund, redeem) is written to the activity log.
+
+---
+
+## Managing Wishes
+
+**TaskMate panel → Wishlists**
+
+
+
+| Section | What's there |
+|---------|--------------|
+| **Waiting for approval** | New wishes, with an editable target, **Approve** and **Decline** |
+| **Active wishes** | Progress, saved and pledged amounts, and status. **Pledge**, **Fulfil** (once redeem is requested) and delete on each row |
+| **Pledges** | Everything relatives have chipped in, with a remove button until the wish is redeemed |
+| **History** | Redeemed and declined wishes |
+
+New wish requests also appear in **Needs you** on the Today page. Filter by child with the chips at the top of the page.
+
+### Recording a pledge
+
+Tap **Pledge** on a wish. Enter the giver's name (names used before appear as quick chips), an amount (quick chips, or **Finish it** for exactly what's still needed) and an optional message. A preview bar shows the result before you save.
+
+---
+
+## Limits
+
+- Up to **5 active wishes** per child. Targets are fixed once approved; there's no dynamic pricing.
+- **Links** must start with `http://` or `https://`, and open in a new tab.
+- **Pictures** are uploaded from the child's device (camera or gallery) and checked for type and size.
+
+---
+
+## The Card
+
+```yaml
+type: custom:taskmate-wishlist-card
+entity: sensor.taskmate_overview
+child_id: b803da068e6a4b21
+```
+
+| Option | Type | Default | Description |
+|--------|------|---------|-------------|
+| `entity` | string | **required** | The TaskMate overview sensor |
+| `child_id` | string | — | Whose wishlist the card shows. Find IDs in the panel with **Show IDs** switched on |
+| `title` | string | `'s Wishlist` | Card header title |
+| `card_design` | string | global default | `classic`, `playroom`, `console`, `cleanpro`, `accessible` or `graphite` |
+| `header_color` | string | `#e91e63` | Header banner colour |
+
+On the card, the child can **Add a wish**, **Move points**, **Take back**, **Withdraw** a wish that's still waiting, and **Ask to redeem** a funded one. A declined wish shows your reason until they tap **Got it**.
+
+---
+
+## Notifications
+
+Both are off until you switch them on under **Notifications**:
+
+| Type | Sent to | When |
+|------|---------|------|
+| **Wish requested** | Parents | A child adds a wish |
+| **Wish pledged** | The child | Someone pledges towards their wish |
+
+---
+
+## Services and Sensors
+
+| Service | Who | Description |
+|---------|-----|-------------|
+| `taskmate.add_wish` | Child | Add a wish (`child_id`, `name`, `target`, optional `link`, `photo_url`) |
+| `taskmate.withdraw_wish` | Child | Withdraw a wish that's still waiting |
+| `taskmate.move_points_to_wish` | Child | Save points into a wish |
+| `taskmate.take_points_from_wish` | Child | Take saved points back out |
+| `taskmate.request_wish_redeem` | Child | Ask to redeem a funded wish |
+| `taskmate.approve_wish` | Parent | Approve, with an optional new `target` |
+| `taskmate.decline_wish` | Parent | Decline, with an optional `reason` |
+| `taskmate.pledge_to_wish` | Parent | Record a pledge (`name`, `points`, optional `message`) |
+| `taskmate.remove_wish_pledge` | Parent | Remove a pledge |
+| `taskmate.remove_wish` | Parent | Delete a wish, refunding the child's savings |
+
+Each child gets a `sensor.taskmate__wishlist` sensor listing their wishes.
+
+Events: `taskmate_wish_added`, `taskmate_wish_approved`, `taskmate_wish_declined`, `taskmate_wish_saved` and `taskmate_wish_pledged`. Redemption uses the usual `taskmate_reward_claimed` / `_approved` / `_rejected` events, with a `wish_id` field.
+
+---
+
+## Related
+
+- [Rewards](Rewards.md) — fixed-cost rewards from your own catalogue
+- [Pool Mode (Savings Jars)](Pool-Mode-(Savings-Jars).md) — saving towards a shared family reward
+- [Managing Rewards](Managing-Rewards.md) — the approval queue a redeemed wish lands in
+- [Gifting Points](Gifting-Points.md) — children giving points to each other
diff --git a/wiki/images/activity-undo.png b/wiki/images/activity-undo.png
new file mode 100644
index 0000000000000000000000000000000000000000..20a8094f63ff84e0353ccbd18dd6d067837dfa56
GIT binary patch
literal 119956
zcmeEuby!sG*DfXqNT_rQ2ue57C<4+A(gI2hFm$I%3W(Av-6hhkQUcO3z!1_osn+mt>zMh_o5fo>P~%xDjl>y?k!F)=ZP
z2koHAUot)n-r0VWaeRuK(x1X2Qx~bYw0-V%#w(Cw4D+;VbLE4fQ329s$_8?(8sKuk
zKdj&7o3H(Q_j;c>=-(Thg8%;p=l{MSR4X)J!#v}q)cLWe&G=WJmr{e5L<9VlmonUA
z?BB-S2=B5;=(70I1pz-3CLnPWR!LnJ5gubXyV^7|H?Lni$IKu7{IEcQSo?SU?RT$v
zvtDax{a|oz2Zw^!96593@t7#pqBe!h%@5bSCCd-d5~Qd4!sj))-_)#2(sT@AWuqvo
zgh}DzssyL&*kzn-57e6ZzuR}?^S8&E4h+~OUprAtb1EvkhC(*a
z1mCiWN1+jXgLRBcV|;yAv=W=WJs
z$G#WSoX*KC7pF$B{wwz3M?-DCFB-`PVh1zfw{Z=q-aR9eIcq7$zkR&~da@07q>Ja_
zZJ6i8uKnZhD#6WTq#03h({$x)M#ju~p&8XJ?GLO$c!90~ReWX>(I2*>|D^(9z(jO8
z>KxZwYl8{RNPUaX<~p9E(V0_Oi-D1PqFl2mc0C;A@46NjIu6G~mh%>_5vW=w)q`s<
zcu77ltbbu?{dVkDllE^*WGY)45EqT*L))58pC9DWKDZXVu$RE%z)=Q!C!jk5CHl8m
z>-WlUO3g#UFU{9mZp<;>Vf2g5c@
z`2OAq*Wmj!XAQ}nd+_gL)OeltL~NeS4+ca5a^?p(%leJ*78lQ&w0}X7$;8jt4juHz
z{r-+YrY1V5$lfN}L;K%1H?)rj=%4J&dNR_SU3+2l@RO3K^8b9R1Y%FX`1m=Mf42GK
z-8vmS>^Fjb=6r86u)vqUS~?)U5cwCUAg2$T#-77BN&YRFb;T6)@6G=qfML<)Gf3um
z%I(hr-Rz}Z?9BsArCk#g9UYYcJxb%E_Ak?yXgw0fg`dda|4ZnNN7uvqJI(8#a6B>{q%^8Y8+{wW9Y*Vs_R)@d_24{r
zj`rUb<4m@%;Sg#Gm&!3~zJd7ZZ0TS>#<@*=9WTy+Q%eu>p7!J&g;em<
z9pSh6tiM-6{*$>MD6a+gYAvOIbS1n<;dUl!2Jc6p*#3_5I*2KV_sal8(=dl)W?)0W
zHiEmr0{a1uPcY7}7n>1PAGU($tZE-i@(Irj{QH1V<|YYil_4iJKVBgxVT5a+65qc~
zmJuP9NoE-|XNYIp(u;hnF<$fUaAQ+&cti|c3)|+0^TvO7{pT5u`914De#CV{W>nGq}%ZuharwJbXcTM?VLhoM#ZXjHH%`LLf(eL
zscA7B_z_inO&+KsqSFQU
zuCt;VwiRR5+<9?iuT9ues(h>GhDv2Udgeqz$oHZfu@LB02K$$iL6%pkq0A
zIs~m%n!4}O<(SJZy{T5xy<0A(KbPge)?Xu8sdJZW-bSRhADSXAPvqN^ZV%BbVI@+Z
zjEJ2ns!@);Ts&of%uf+^iCWgI>olfHw3#}(nmr4tz$_Z2@`>qMmr%#+8^YKe=xn;*
zuxuUatB#h9*eZp)7u6N(q6s*T4-<{aV1gcA7aKJL$sDpnh|hzy8`rw?Xczi<_Tvwbo9bQUvV%K?gD>wO9y^k1WhMFLA4X
zk>5J!y#Agb#;w8brD^lNXY5$Gn;V*eIoreEZUsgXJwwPjczn-l@~i$dy34f`bjA3bc?=w^uG{W)np3&Bde5?Y
zD{z5dfv8#c>heUYoH%Xm@JFm7>er~E&(6#yYO>!b8hv%pZQvrhgF=KdgEia6>$Li>
zJmC^1l5d0QU-2up&pENM4`JKW54NIfd_i29sri8>wcm^uWwA+Gzn5H@Q2kxi*2v68
z8nswHS6H*TVX*AsV^Nl^riQ
z$F!V+!65slwMu49W7e-ZbHm@daiN}Gv%2@0_t1ZT8=P~K<{9@T&c=qrsUo-sC=(_Z
zona~wegpIK`opD|lYCod?Sw?i(hj)^(!~!ftxbsFmbRdR7$pJxAge+)$m}o+nZ5`$
z_~`ulGt7Eu2mbARyTa&}ogr+;l2M2XqRdKE9~fO08EE^vM@*r+siBz=N)*w&ac4@}
zSi~e@*9sw}3)NEg-97QPWQJDGnH32nKT5Z47*uPxKTl?2
zzO0;XH-aj6H2%v5KNR=S31Vh>oRp%_KC1+PHDQ{#RMjj4Pq}J8*5CIFd?$tVcF&54!`5=_YT@hf!zc%%bT4z@hP;P
zBm2){iO6&}6CBuT7x$+lrPN|CHxosv@4+yd53CFY&6DNxI%(>`E^Vvmeh{YT`t~z62(;!V480ejhbhCQ0J`yxr*+?{qo&^2rABMYIZLrBSHHC;I+xf=x*CbfQN2V`Rsv;=-~+0Ra&JTl=?(ZMGxsbxoBU
z#tW2nEbx3yexlfoN0-!5V9oFn&|E648Cy)43x~`s5OPhN??c7KmA;Ro5eKONyrL>?*Hx@bnlL=$1(Dt!p5caOY
ze9Z>4^X^fq0IO`5P&5{m0OgSioOpqO`$xVd*#3as8bRLcISh@*(?TXbv$D!;r<(!G
zv>yIY=TDbMm=6D@xp^CD%u)tsUA@exCBQ+(RbmepU@u(7O
z2^hK8k&$KbUaN0d?UZ*Lp{gRzqV}nR5^`p(0R>n|Lo8LiPD0~)NwRiuE{-vZxw^nO
zXFRaJd;SNh+2lS?iS0PrmHuU0p+}YL@113jJA5fNw?+PpCw;w=p^5oAaV(&)SrWm_
z^f9=Ats4Sb%WA^prv33bnONIl3RS8ElK~A;=ETtaG>;=3jo$xW+;rM^2Vib5>U`!#
zw=k%@lXPxawcW{+sgqH^c%vMKx#pMkLo}uJ9+~{8vp=8>M|f_jiyuWX#RIk(*lv-^
zvKiR^eE_c)6cDE8gR-E%PD!F_?`SA<5)liQeO2>bw+K>HkD7>8gWw}42db-ip2q%l
zaTT?1GN0TCN6$~2O>GXvBB#~#`Wmd1Rw7P%*p#F9AFfO|e97)gj>KYkkH
z5YyINC{tC498$ku?5LMMR>8xSmh)$&LCQ`WG|_G%RULQP(odPCoBQYv2eza8VTF%L
z2q8xYt}Y<2r9FxclDqB;kP#}S#bgFDtbgkLJOCMKdyg;V%cNi>=zGz}QySNAK2}tt
zt|xTo<_9|Y`XUFPPb^*CQ`{&CYQq-xA}5YPTNq4#Fv=^sZarbMClGFTlLcG*HN3ZS
zGbz8^tE@DYmK9Cu71PuzHEZ?McvSmEe@CAyJqr$B`;cb7o9xya*ib|eBM1vAFbf8i
zJmZBdgQf^{H|$jtbZ<`!p`+kW4!-1yLa4=gWGG7>4a30wXg&)uvg9Akd^1RyP!K#t
z8BLR#_s}`B#$l|=qSno2X`06Fglwx9zD|{UgIt}KJ8Xb@Vv`~kxs&Qox;K(fE3Kc)
zfO#7;E%An0;N&n+rml>tO9v+0vl!yJCF<&y
zdWpF#Mb=8&3s-0?R6kZA=1#GJi2sU|lJDPNdCFxka&Ng8zP1VeH9_v}CQGYH`&(yn
z3-(<+XUnoO^xTi4Z#}ta@k^V?k-N_ytxNNKUUK-9Lqn$_t(K$Rn1C%kkPcumSBiv$
zg{VdhPu4MRE`zYUE+geQgS1rfTkUE=s7kG?-
zp#0ZapyW?>E~c-aTgy(try_X_zb3Mz2i08U1$Fj^N_Gj;9FNyQq>=z-W(@gq}U&
z-k!RA;Uk;b;fL%+Wg_^Tp&TWU;f8EQ>eL5?ary2gHb$#VN7wyN<8=8`#W4O3MtH+Z
z$J-#?;rYT)(7Ajo)3ZRWyT2WDy7m6!t1gxYoGS^F?slCDW}?PA|nQ8rKh&E$>@t`BL0eOU*M16%>?lX{__q6_$Uakjl*V%V^oD;;?eD?D3
zsc~m)j{oM|hY->(Vm2c6PiL6buK^>vWAX)C#o}w5uKFJI4I%QIIwI+rT5(2N9EzzK
z8S~kUZ>?O?ff1^+35|HnO|`3%VC1e!|CY7Kwl6$hjbYhFABVqYd=0P}LtbbR(F45_
zv9d(@BD@u{<*>fhji>w_&|2ik*F&-UX)UMF*`QLFH+g4Hh^075M4fStEot7b9zcT=a
ztcgx{2QH$a?J92!i4`=;2sq?Z67Dfn`8-EIPcRvo@R$(tt~q|8SlDiNc!qo?ZSu+a
zv>4yp{~C}nFT#qSiVP0wsjZRdj*D!+*gXHc2&DKYGMLQYU7U11Fs3W}5l#)xfUPJTl#qZ6JJ_t#Z
z>=m!Vwt$YZa57FnhyB+FIgprU3R9O`F$8zWN(mW`HD4`GHkd0mSzbPkR=dh;$Op}W
z((}@tvmD{~0PD0kH3G0@C~~Xc0P=Q|p(3p!{m&aZfN`L^QIb-&0K!ThiToR@Xfm_5
z6wz^fk(9KVv`0U_SUoZ0@mIB
zPYb;)dg7s!fMtA}FN~}NYBSQE+eNBOXZoiZ7yo#5Ra<;^?*O+Z8~34%=gjfR{B^Fh
z(JH(pT!q0C@5TN$twrdh>mI`-44PcbFk7wRo$t8J-f^!Ks*6I;jIY=Ll&z*i(k
z{hq`d(?dKX6p3o1v5FnKT4P1v?(fnqji&U467`qYoz9%Z0b(T==@Pox&VY_0$|#QQ
zS%-Bl_V&GWv9%5`2y=oik5v0?Z1opcgeNPstraB8Iq!i@%Fu4wmDv(RAGX12fT&f;lpn7Fc!(l{lUN
zRAI4v@H^9U{nRE9Y?qAL!=Mc|!1a;ic5oh4GOT|632>e~-JBmqE%qMxthI3f0b_sx
zx!q{gg2IILAm_80B)#Frmhmrs?`l(U|FRYi8z@OzuOYZeWZEKQ8P`+D#irzjsQJ?E
z?`gs}pS*sF+=d?)I?mceiBW!~Ev&3epWdv)qV3#=%&3=m(NcFJstlqR5!R(NO|&w!
zPqp)1g`(;3{h;ESIid7rKSnYd8Y}38bc=FtehN
zYPrwe>o1pQ2X`{cp;2CbAi>*E3k+Mp?Gkjf4+Vf)GCEf#;<>iHTF%ClXpe}JCK>l!
zm@NhwvK?xWD`e@Gdi`CN5`^X$bs~XraC{c_?e*A*1=e~4zRvun61(nQF4R__X!Z6*%k9;dd3{&GahM*5BA&
zd}A@-B2SnQ+Kxte`&cS`)!f5c+2Q2Z!>_FYlH5!y6KpK*pI1RCtuy2(Q39Bh?kZF>
zwsiSk5d269{Vjja6%nOLH-j{#(6ja0`mPihzW)ANFkl
zdtrR#;7NU+o^=PlvPaj9hxrE{lAQ@f3(uL_OO2Jb1#z7Rn(6nz)!}ecV28LvtW2l(
z2cq3$^M)>#a+Re{TvGkseMC_l)jQ7FU-)fT+i{;YM6o29`n{2hflr#2!YUO^r@VTZ
z5*D%S_E#>6gZi8lj|H-80plTCC`5o=8fmt7wXCHW%MtJr_~;zKtO;V@N;?J|(7g
zp}n=zXz|AF(5M$ldR*zRXDgsK6Lt4T(yXx7&fl?UYLXk{VLgMrkgAP?G^JkM5u
zuys4$u!X`5%KK)Z?K%b%=&<8_=G6F=1{DfQNxHqxWa6$$HCDxuNJar4TACyt!QUkw
zT`q;W?6AZdC0yyBi_a|ufS02w8`jwi`BE~=#a>}MK6yWX=8Jww_hiK_GKwW)-l+EW
z!&}$;cq(B
zx-h{rJ-Q-0i0o!FC--13-I7|Hd=Qr3Zpp>7-DEuyiK9=0Jg8#c+4DPkgx1(D}+dAHJL59D+XLpqX
zx8@LqySwpkvLSQzI>zIMlq$HML7gU{&Q%ScSY^Jt%ap6Li)*?KMz>e_bFe1~+F%R{
ze-8|_SuWH3M_@2D4+c~B5Uh&kr5-v$gcYl@|4uiefJ6G|-D?f9T`S#&v;-2G+|E~F
z>3n(yTzb3Pwk@goK2Sd!?3^mf}-VivRpk
zxl1Fg(h)`stFaxcvFO6jFDyLmmC7kDD3FKN8_~xom{#h87kKkd2Bi51meL9Ku#W8H
zWXi72&fkkpkNNmCpFDXo0yWIcy1L8#p|RaZf?ii&zqGN@0DP&uyd3}L^+TUl{M#Q!
zp!B!D{Japoj)UX^kUkJ}Nj^IJicPU^aPX6dHupwujMS*_UTfh%n#lIXNUo+se-xEK
zjoYTyoKweL!xk@R9r&njK)YFOZEZ<$v8ICq7n{$G_z8%vi_3Q{Ev@+Ubk4K^as;dU
z9n9XCE#oO{YYU>Qt6SXGCN(qgvv5`hLwijoQ0LXF$BHgp#1S6aJ|SRU8Ae1mTHlUw
zaDdm9k1gPScxJ#!t_>%dQLsigZIzTF{|F4(^u<3ZsLL+A2x#Y1V!6m0+H~s!FRSWa
zXnjBUX;qzaX_#XNM(*GU@bZ(&1V0Upj3#DgAQIh>T6O^eZ4l$Vdb5|Cftf@gNQUKl
zUESS%i%yjO6Bbp&W+Usj``7VsPy#^hFVl2U7ogAPL%2^G(X9JFv!ok4oUi;
zHVYF{Qm7_8LclXF2}w!YvyHBY=YFv)N&SzK`tzrzUKy0fb5n(bhb9aS4aa9^%huMc
z6l3S0uy9glLAQMb}3#x+^YLJU>5&K%t4?*_-}V5cJp`kG=##R;f(&1jy==#4%P|W1bO{LwV*aR_gRVEfKR@*QLcao{39+-A7#(FQohaGav48vK&5L|4
zq_iQPUZ&jwO}}6vV&N1OjM_~yf&$hI32!Zs
z_TLT5mDJUfIu?1|GdD6N=wsM9ILPpBg0Kh%TzHMCm(85E*VG7#W~gbOM*Pgq&zGB+
zn9xL2((>>P%Plt$iVGdb{oUlekqp^T%XcXi@6o;cr>S`rRnPEyxCeWslHS=3##}S9Ubixxat-0
zZr6q3^coK63nK&z=YyU#<{h_}Ph{vZB-}`e$x5@z!1JU)J_l**p|86B{;kfBV$S=&
z!4cTI0mWuwk}>#I(r%`0BXEPOd9DK71BzpqAn6EPa=6s>aC)Dk0g+>ntyJ~6%4a0^
znyw$DEnLVuwj9W3I<}XTC_Q@g==&>907%RIf`r*|Vv$`rv9b3+p&p-0{X&~TAnX`o
zN%H&mbH~SZ6q`6P3CoXe=k`0#;^H8QZ<0uA7#f!J(EF<3i)%92KiB4C*#yfM3}%SK
ztl=kK66}v3e`W!v;M<|2dzzsJ-YLf7?494qpvh-@AW*)#<6qHrUGp+t-uM3^>DqBr47U(TqiOJl(ELrw-E1s1P3$^F;G7e>H>qooKk3JMNN
z!oF1(lS%yDkdP2|PEH+N-Gr^}?fg0((Ug>wR8d#f{(xg`qA*zy1&FP!rlO)^WfJ`E
zUSN{tV_#?IDv#aSVgR0x*x0t4wkrfeDPfb7kdDy1CFSM15J(9*w{a0EvwZSAYjV$~
zTk52l!NK)Ra({p97V#v0|CoBsq%*6rN-dVVUs?kIhGC7(mvLeK*SzZO4WA`_Pi&AI
zBa$e1Vj?-6gqH?+q#RhfnKNYkWN)Fe9fNQLrP%b>60|5}w4>jL#Q{wG(7LvPK?;j)
zcNCRm#k5l+dLiOI8xp;6CAB04aq=L0gbCn6&Hv4Wnv#<_TG!}_Q#kg*>W|Eqz2Q;_4ol}j^OW?*@7VN1XOGHX5n
zji7hTt=RQ@1*%r%ihpiqri8-GPqVW1#4v3Cp`@gVWp|XOo?ar@@Z;aiF(gt*OOIv~
z5L9q6@(f!M{nJ-0o2{qw0s(`6{>0C;>9k*>wtbE#^u;gKVkgUutbLkaS0pDVUz;{l
z&k)PkE>tV7syc{`!7MXe6@kXQ0g64Cm{-n>4x60nSB-i6I4wtm;z@6%+b>pmjvI&k
z)nbvL);7f#&eaNId=a%UY!g=;?MvXOwH~4etyF!l4PC*q`GHt!7+eXQ%>n-ww;ilv
zLci@Wf!-k(^m#}rrDH);lUVE7Qe?O8OAyaT%853!4bId;5S^rxcHdLzTWf0$X69Ud
z2U`b+i9{|Vx0TMHc+36FCiXz}49yW@}`f9FBiiS?cm3dn8EPFn=H%Qm$
ztmG-i)x7DAeMZv&VC-MJV6h!9(v+0aJD!x;sk}NiyLzOEx>%R4+#D-3+jlmqhw8e!
z*RpJ$z#aF-gvZCnH`t`lBUnIt-t1+|)baE4tFJrgV7Sz{d-rZ^-d^Ap`eQ`INN*h5
z@r+&N6INDvVyQDm?Tp*uZD+LCa8ST_&tE;D
zeF5ojref3AdxC%iRGdSUnu0b6NE1kC?xg-2kGh(g4bOIT20J@@UR|*$=&X*N5tsQp
zbItmWZRZ8pq#?fACzj;C)YH_=#wHeEHsBFdJ-w3e-?e;CcPGH66&)=1oZ6r>SwU6-
z*mP;01AOYcVY7(Ww##w56SjbDY&1Y|fPNn(!(@zJNSP3>gq42(&JQ}N?dk5E&)H&_
z=p6yg$AXkEF|{0^Ez|~Jd=y8Kn`1&&f0CuYIAMt(VPe8-*`R;ba9e1#RRE
z7hSKmlb-cjj#hg4k{3!$C#J)pSH|0hlv6%)4Oq|cME?IFpp9b*R?-bH?8fY
zw$k0scS8)&;KH$K9<-ff3wpO1oG@WVeh*o@kMrE&=QFdLBu8rl+5rJ=v_xT6gXz=T
z2$Md5ST%3^$&1UU4rB-zJrFbbOG_4tqdU{pxhH$tjxlJQpvwrHoJfFzfU4Y2HoZuUToZcUUv0w@k1ys7GG
z5^`ah1$(4pVDLndTGS$w*(F4*`1PwmU02F*!-pz=O=JyM(MAxD0)j%(!j24XcC!zIW!Ba*gjNGE?EHuD2{*T%x3_nFNBs$_N^(}=SD%t3t`~yHHEi3<#A9rF
z?4~>SrxX|!L=!?VW9Hfn!k+GK$l9M2!$y~UP*Kqjzl_|&mzxPx-1#_cIG-KoBoO@Z
z5|FHAWmkQ~RF$k_>v7^Zxs(KIBUh4$VVwJ$VU>kk=TY4&PQwPL>`%0!Otp7m4h-O#
z@MjJ)HHz3vgd_Ciae)wkEf=7tkgE3q
zU5c8|BDl^0&RP#I-wQZx?v9PeC8i$-kt_pT=hpRWfPC73UISp$w$s%Hfa=;nnmZO$
z_4Tn^U~6mJblArsWZ6xqEyb3NIelZ|C4e@2_Uzqw9ktAv-F(W-jA83RH%)AwZmFKh
zA;B>~sT$8c(+p4@FvOqVzcoOgJ~(%8o+CxKkNfU>dMMS
zq7hURFeWS&1|>ReFATnGh;3S9%oy9
z+~U+i8W0-)LD8@2Zl16?&jkm+5pOi2eidj2*EJO&7`Hx&?+#yG3|%G9hgRT)@Xe7@
z*V#=@DA&Us2&q~DGicU*;|QxTAzhSpl$R<(usZ1Uzr|l6TJYYVM?=yJ*>y6Y7V!xPu<$Cr+mPE)7sDW30V8xwaf$QTSyaC+y^{>7;^fJM1Q^zb(
z2R^N_5o|%(JUMEG)g818Yinx+M6JZ_OL3n+4{v`VhM@0JqTXBA!=p=^7I!?*a{5zP
zXo`KLENDN)ODE;`sJ70ScnC5Fjd&W
zu(Ph!w9=S6sXLm6EwT$M-e+fxmv0I_deqgh)e2fXsL?GzLT0Kg!^n9|%S@U*s4~Ms
z2q?Ay9m5LG%k{uZ1$TG%nP$(*3gE>^@gT{?s0fbpcX^wyiV<5I#oC43sO0_kc|fTO
zReU$KPxH^NtJ4F$M&x-p5Ga(n3{6M#AbU+gxFGiSI;yJCfTW7uBzc&P!vwA!C?F7U
z`LoaQ@mL(~U3IaYYjPL!KFr$!@aDd)X9Da4Qir{=cIa%wh?fJ$YUW$P=!hdi+kol7;RNBE#
znZ25%@QId+ue`8wWo?Z*m#aV}g{g3?81RIx{l$)w%1V7eAV3>@Eg{9jGxT)Ls9ev)
z{}?=$r#b<$5cQ@;!+JjO%AeWq6=Ll9F0F+C4?P&$+{Fx5kS>9r0iP{_!JzG__D)QPshukz;X9jSjF2
z#5{JA`S5p-VP+z~!p@J@?Lfhll$4BuX0>{BUISnhGbWAEe(~x7-c3Q@6MHU`CY^zS
z0n}0ERT(f@gaid21IgvOJ~#pB%JHZ&57k2yaQPs#968QAdjr7m8kQ!NaT@_w#d1GV
zLoJ2B>#3%M)8C+vA3x^RE%srB1<;PbaE6Gp+bV{2vrBnjV+7vKh{`O~&S8OGOyF;H7uzEIAd&d!a+
zFb3i0iAbbdE9kSadBFX1$72N9+IA4_`1r|_-iE#97-`{vfWPl>qj)}#6{wD3vHjME
zXLMq2FC!^1>4l^P)LZ%8e*xq?kX
z5@<4!aGNi~nEoUl5r|E23@!dM2zf?GaO=bZ+D_jAs6LLAZ<(qtp0q4Z43R18|Lp{?2%6DpV-tXHSY+e
z8k6D|5QyGXhj8puQHzQMUivZP;D=lRTexhBl0R$m`-S&YOmH{`;VM|}W1qvZh
zf9~)4^ZhOPcLHCBS2=-)k*
z-B<@{K12>U253V#G^kRgsqbd*=Zh%6PbK>s9BLhkOR~DU+TF4MqQlMfdc%H27Ko$F
znl9+oisi&u_7PDS^U``l!&8u-zxPf#Nbrgp8m7D$08mlz{jvlV0lYh)vPflDWkU(6
z?m6=pehX5K1s;Q$+yyr!p^^hz5+v=4p~>QMEzJ?KH{VJv9nga1tECl9C1$z^$Dyc8
z5%0s5aPK3lWIV0&tz2
zoaaMQ=rR`<7eVu1HwRJ#3e75IEKf?5la@T1u^g(nygP!bUtd^Qc>VPV1asoft-1iOpAUY*5U4TBOEg3dlwP3Fy(
zbqKAnxoQigpuH;{LEJ7ac%At|!1vvF37$C0tcppL19?USKx=T?9mx}Bf9>27!X4xh(W51O2BI461~^{
z*RsE_4+#*^I2N0sM>#@_rUB<~Ez>f{7MtU}kJfBget$XilIVUAj6$Kp+otAD0U(>;hXqYkc|XwAXU<3D7YRShq1%k(BQXSQ=NU3z}eO
zA1#oJB^4EkKwN_`M=@0{_MD&eNLL#J7YR5GKp@3LodnBUsH8vD#0tL5kg245^fM+K
z0;L|g2i&U`@H-LRRqY~Rd?0i60%t@HtgQPSp2N3x
zDU8zwtkR>39g2L=Ja2)Yh??6AV5=SIxtf8sO_uuyv8BnZ%Lwxy?
z4W?K6*o_49u*yKpHn();epXhgEaLvXdu|K{(>a?i<(22iY3EC0}@E0(4!6FhU6<|~MuOCt6GXFw*csc(7H~$21
zJK?l)xONkmgB&zEK%t)~Kg~-;5g<;1i8pHG*qRUQZ7$;mjnjp|cKW~zXJ(zdm6jv=
zw|xRJpmaHFRo@xZ*{3`~7ZnxpLa2=U0M(3QssMZ2jadv)Z#8vHszin1iZ5ci*N@yc
z;-K~L4Oy(h2NO#-;BsvNZk~9sXD%lfqRIU5;&}+w-Xah?(V4{b5>wg92*BUOFr3I2
zXTQTipS#0|^Lqc>%@}{@MmA1P<@!o@PtP`h7D1?)a~Bz1iPumvpDcsl{=0FHgx%u8
zuOGK!bz1K*O3)A8($Cw7-hXZcItblIMQ&h1K#bxfrKB!ng&3Z@`cDYAv@~PgdZ3_7
zfzykv9iY+5K}QCSZyUs~`-F}t3|JeZ2n5hM179WKuS#}9C`^Yz{~4c|q2}w9tg-0M
z=QQ}<`Rb?na(6VKr7$2%uxNbH!_bfL=-+gM0A~P83%@WcR^RCN;Q+GI#`VgOT4N;e$};CCi;I(h*ofa
zuvrkZjoJ{S){gCC_D7H8&?kuP!=mKnmX@`S3vJ;t`VQLuz$MBF4ZRII
zccU>k7T$nw+a1w12Njtw-Cs7dQR)SVfwC9u2Y~|m;%(G(6zBxGz*^*
z1crJ}F(@-Hv`ZHlo}B(~r>myM(oFql11Onjo;_S5+6}imRRCh2NK2am
zsL}@)rB`8WJI)&(deU#~AqPkkpnU*WN6qs;wtfEmIZH8)6+7{u5rK}67i)`4SOKO5
zfE|q6+cv_Y~lff*|Bxx`e6ouAS+U0tGmFMMV}
z_Ym_vDeLR+ci)|DB=Wboyf~MaJ6BHOfBO+@t}J`+O;;=Up6u`iFwoH0A;;1j+YGD+
z)4zbl09XRU85QmTx+i7G3QFs-+jehn&NRl6@l};Yh~^HKX-@*(Qhs)J25kk;QBe_O
zT0FpKeJ&k#9j|$gp6|Lf2o4J1&cxJI5%5!5_kR)4%}iZ(?mbWBHYouHKoOWL0;OnJ
zZ52HZwek54rrlBN`lhDy<_Uz&bI`J!;iTJ;z+<0QA5ffmb+&=omYcw~=P|Gc(|0$~
zAiUcjNK4I(Hx?3r6u~+>T1LFzcdo4W+B$OC$1dLm7OJyKvZM%Jf0%tsWy8ehh|F6v
zZ?oj@cFwPl+ZIMU&5@6rz6*DDH8EY{5QM+fmSKF5AA0ZllVFz5rmSyKfA)y^tp$qX
zdR15>7KYqcUHFgEUB6NdMv0!z4*AD0!~imi+*@E+AIc1ywkOAbo3rNU&VomJ|Nf0y
z!|00(zh_sl4fE~E^1INnMEeDDwKU=KE;tH}mSws3(?+m~tK92X@EsY|
zfm=o>Clf$gZ9PN>U}k|_#>Ue#d7{h`60|YWmruLF{S6Om{C>j^UN>=ZEdl@Wx;W@D
znwa|mhtmLC<}vn=&!0(N=4<_4b$OwnUSmN)YOvbc*=!i}5
zOBNSMtEW+VAi@MF#gS5do~$*dYL9}b+^ZAeS{{Bo&xhd=5v1I|Ah1B00g+tnszKLo
z{N3IrDAxIiT@p|`itDssoa!ORN|UR@e$XR*NeVJASSkO#3ahNWJty!mW?z@T2V(|H
zP#qidt>O>xZ{=w{X>!|q|Lnu<#i}0qQdr5iTCv0PCdUP-hhy0u4)2PJ9=ibn(VLkl
z0V~z7#5bXiS9+V9VuMA>+pdE?mf}B-qg|@Ib}iy**-Ziy$Fx5s*JkuVN*SJQ$WG
zHV2PM?4O>7>9EV`=sW;cQ`_yNxnl&J0w`lVP0M~l4_z^`gk}U+K|rT1?5eRYu|Sne(&;nAHGSK^qoZX*bdz$
zrsqW7bu0!keU>}I$jdwIaBDycgVZ)|^P?)d6JO(oI0XGL*wKAydD$7zq{g>j$N9nY
z0FSx2LNYTm=WaPFPYt$bWid88B2BVAdhk8ne%e4X$1fWW{oL2r-x>Kd+3Mz#FE@-2q?nktRK9=zj)P-5PbZ$1L`A~&_m9X`hMe7Z
z27CL2Dms(g?I;jfyjnVsz4>VO?a4bKKU1|#O+R7Z{=_v(2!JryudCRVl-75hD+Cky
zwLur!=!y*bMyW0XJvT=m(MtM^SJW1Y6DY;mH7@zTc<};3e1nARHTuJ!F9FjT(Ol)D
zy4S)Jk!+54j39N0wAHdQ&N74Q?h0O06X4Et09Nwo1=$2dh~8)8VY5fziYRMbZ$5>a
zVfm!PI>VRJA$`vP(@BrxEnVXlFH#&{_pNa?&9Y-aE6zZ2YHDg;8|RF4Rq&^Fk<@RE
z2@fyAn3MLAzkK=f$KRhH5coA1`YEx%C|c3)KbJmzitS&0K2mvjc*xqUQ4`wUE)6)q
z`>WHdO9pO}rkky%F@U+5gR9y{;;L6sot>R}
znLM>a?Erw1Fy?7rzPvl$hBd!2bC(2{$zA$YefKT+-wSDI{7pQX$jD3rF3eN+tp^&~
zI)d!%eOx^cU4l!cPb0#`A_ui@yuXIW#%a>@01SVi)yv+oTsY3acKM5_U-)0#y@x;6
ze;+@3*|I{iicqO+vXbo7Hx-p6BqNgSBuTbx<*R6r9VII}$qGp-QQ48ANJt{{Jm0$S
z`<%bvJkIZYAJ^S2T`r&Te!s?ZygnXHYUkYCTo&ifZ{-SCG`(ti{CF6NtI5d}1m3JO
zNA4MA$6UKs&3$sr(9%-)m)EY;)Kvb5`^Q->B>H~)_D$L2J1?&9iAU2c~EzhG3TTQVWR@Ht~QhJF)fA;*Sp1P4W-7`(L1dECuB_Qeh
zK}KfgI)skVZ)eI99lzD1j~##1PeVa;z$K(8jHhdT*jUG7ri|+N>t7uMZPtmq64H0%CCa<3mG3
z!?AWPUG}?hg*ogM-S~*B7Fgr9%faS~jEr
zg~~UUU}R!)8=X6O*SFoIBtrCVp3bYY&95(ui2PKg7cwDD{?~WeJUSwWLS6^ux18L>
znF1!u7`;mORlarWm@^KqifsxC2%x@Kw;cV=U4@H_tNN6jCcb@U_=n-lLYsZDle*}6
zHf+|xVR3co`)O0phSfMYE^^~gKaY+^0Nu6(ddeQAqa~EO@llH}{?bu=mgh-jWv|bE
zB$?S+PsHdNtAgaRGG5@-PU=#{()j;cr6wvWs;_OCt2c3mbze1|SrFg0ZQ#$ImIql`
z8ekC`Umx=^KfGt?{>sTnG#$}bpMR9OrIlYaO^~Ac*xVq+z@qQT#W!~H$_UCKCjVMC
zd*)vR`Z5U!R7)zpv~&G4D_JBdYTOWjz+b1m@IoG5l6~9M`Tq5>qerO}=*+FHth#=E
ztW25G&ur5ajh$TBxRXAR3Npp4++6yu)|K18x2q24d}z-p@pkc8@m;%a7+J16$kScs
zx{rsJE$ZZP@y_*~nUA(+Th9)|@1P9^`d
zCT;^*ldo?xBK8c|PhI7&B`ddU6m?2g+E)ojWj>4q0*3nptwBfmxlEU&F{`Rww3|j=
z4WRvPWR`y72TA1BSIxSaZNk#ht4aFyH5R|IZ|jYHB|{_02x~jBu>-??^ZMoQxcGAu(Jhdm|6}P&
z0LKre{qk#Pd3Slq6SRkgSEl+)<9WKk8owt`RLNqoDqx%u=VIE*#e`&xZAJdv#JQBx
zd(b$?=w^#8dF>a)pTY-vbS1bq%FAbF&zA`m%CK7
z+?|%K;^Nw8&TK=o@Lh`j{vdlqJtHHdhJ}R?H8r)$OE2t@Dt&=J-tX+>$vcl9=Zn-$
z%gofNvKE*|Qfn8KrL-P&52ENeBD8@N+wJBi2WG<`=lOYfc%!tm{#J+gCb*wCd=K@o
zu&|q|7v&Zf7R=mO^nq|;Gt#lp(_mZUg)gL8x>pq#vy_{$-P%u&7rr=o@+2)iy_c80
zRLxZ0xo_Wx&)V2*23eN!&i>Ge6D_%XpScqkR}Mvn97+*|mSg3=LwfFU6x!_jfB(i2
z(=AKUL>4ChIW_+GO&sL{H0*!Bsq@)`MT7nCyZ_&Rb7Fhj8kZZW0rd6#QFfF6_-j}g
zG2oE==T>nrmP$CbNp%<9-*1S-Z|9G?dpAH&h9=qu3uSz
zh>keC2`F#!htU*+t?Yb!VZz#1sy}@AuyJY&xo@ez!}!<*|4m4UywG=%AyYr;if)=e
z+8Eum8uS*EsPI1l$Y2|9wv!h@OaoL=2euEz$Fyx})AQ#V*kA^0BKICVn5(3F-_Yt=
zC`au$D!IZ-J*VUb(4NszLUlwUK|BrYDAjdxk^*wW@BPw2apU&wg$IUO`2==(aaAq+
zWJdF0DR;|4@y;Pb!=ONh)lAFp6~U`?JU%Z@;tT*Zq*%ja#|EJ_B;P~;-%u`w?Snrr|5OI_F*
zDQQ|Fgzh6ICMN2Yu$&wx$Sj##`=8^qaDRb`PJGKuvg&+fbHIn@gi>`3E)vS-;=VFj
z>jt51+g9nOact4Q`wUvOWP`0impiDb@Bv64dWCs+#1Uw*b~XwNr}SB)3q&d79DC7S
z5$LV*g&*qy!S&aaeTg%*C^m7O=+{JE64|kX4>xXNa*~PyO|fS7yV{Q*H=xSYGB9Az
zJy{jqTX8`<``xFPx3=?cw~Y)*TDuZVig{Qxl(%8oLY!ASe)zs&S=QC)=mr$(>v}!V
znrls1LLr1yQ8dv3CgJ7_<^$WXg
zAs>&FS$>5yntbHl=>SG-0bWH1Ua->1ZQlqQCM^C5*mZ3gG=oYi`p5olIwiv&Rp$0(
zUm#T|xas7fkEjfbn-WwakTfY8@lq#bJSQv$mJX%q3UA-OhC6}|84{=Ke=t+~;6XNu
z1zPRew+U!cf1$jF&Et7<^VFN|!he@(C{?JU(b1#9U?piN)HF1*_U&6M8XF_|0wH=x
zEh^$dWs9<7VruG~-AC-@XV`4v;Q12NF7ty)^fQynQ+gFAclCC}9#i|p&cf5OuAiQH
z4ML%1v|in3y=d$z@Z&Xra<1LD5e%R^*@%9RDdXzZd$4H3BO(qRJ{*9ia6lH_3Md;Y
z19T1H~KYOM_smA7sf_y8IUx5j*-d=tE
z5L_oDPIS1DPQ8y6E~)~5z!#l1zdL^Lgy}$xSUdG@bh>tF;FdPb?^P`
ztV^7usFG3MOiR7h5s5iryL)W1C1zg+fCwu4k?ry&Ig%}c6vENbD)VRW92g&$_TFf2
zY#b_nEVsi(eg93Fnt>f9ap?Qq-Q_9$*o7Wf;ohmkPF7YfYyGkXx3?AzlPlU1UKV=n
zwG>{vUVa8epxDaZvoff+0Z;(aa|LlnKWbaV0Clpslvx=CRc)9~0BSSD83sB!x&uy1
zF8vz&?vp#o{Onf_~8BHz11Z2F?SOm3a2)PG&Q-
z?Lp9$&`?0RyeU5WfxD$u6ssN}sNJClPf;D3nXNY{?5Xvzj5KMM1~$9S%m<3C;PmuO
z6pbXc%lR$?S`sEjjKHL*CZdK-*o`W
zUH<&E!7A?=aNIAt2HXf!u$DjeM#|tG#BapIAQsN<1$#X`y+DM1t(5AlLuo?s&B8bK
z$=baUvfLJubNRHReX+?_dNJ;Z;0y*yR<`0B=9ONnf<@Lc(bd+~QEeH%G}6B9^OrB^
z{S=RXprxRK3XXdSU}^W>y`e|`lWSguVG{#q2ENvdY@C%UU&DRUbmRI@aX6g)58Odu}!r14Nat(YvLABM^SCqkVH?z
zju29Nv&)~q{Zt@D1F%Hp*oahY0bR7pz8JmkDo5?Se~v&b;EIDwzNh$)HQ&yxi;}?m
z0+CQ~oh)Z3267Sa4i>?#mA?YvBvlA-~aGfa-kwxqs94|G_>TX
zCs0z`2i8ch?Bu!2)|AvJ6t$~Lx68?WS7A;bvdZnj^EGK~MNiGR01}%{o#@)(}gZ70s)ON*P
zURTj>CfhazRA2|E-@8Xm5!twLOpeL^^cK&@mvq1|y%AFs6{QDXa@K8ugjmQ?(O_V^
zwhZJ-uB_Hy^R=6K9bW=%#WkU|f3y}1hSkh0c{2o#6pj7+_s5^DN9pJ1F7eg$Ve8PI{=&2&tJaO@$^(C`{M^EjtIJ(vu^5G
zamrr5wxW(Bg$ZC(Y6Z<`Kq6gHIk~yqBb&i1Sk#BFotBbN|MPi`S-Be>!Z&IP_QwZ`
zj=8$JdMH2@?~IrN%AYRrUBHFAs)
zWqBb`s(r+5>aW)>!F*^d*PGGlGS5j7Ep2T}6cI}c7onbg?Cpcht-knc4J=Ox;#Wbw
zwP)WrWQqg}-2h9wMC1Kk7giQi>SJEN3BTvh_oAR+FfDOF)z<(*)@7iUZooBWZxAk%
z(k0FK#6(H&bIyZ<
zyI44;aoO8j#_Ad4dNps}W4UHEH^h$#afSsw3^#Qur$euHuw}E7635IF)>M`P7a7spb((tzO=gWqog()w`Hlz+8*+-l4mM)hK%{ilS;sk
zv>en$1En8*w8?`0_`VxxWgWtKQ&ZDcF|mM72VEpRbF66j%b=NcMdbtq
zo>txm?To|1Dk}Uac5{yjokQ_+t@%rt_a8ZgPIBj1x-&(b{J
zr2U?42oNsmXIlwcFMB0t>yl5}Cv9+}V$d6O5MoXf)OJL=0kLWm@
zT)KF1r}@VGT~-|XM0oNgPuMx}F|K?{>-bu)E!RMx&dmIqs@ij1SJAJ0D98WDn%{(k^=N)?
za?D{K*xzRataJ~d&%d_SFr~Q>q`}@-;nJF3~oF5kU1}%H(-MALM`R-knzYEXw8=yOP
z6@ABnX-V6=U|42=xa
z%nd#Zx;#m~)K8X$5bubC!Eob?*_K2po(3U%t>4++?Qd
zV#4R?6#o+fhvSeD$Jv(op)zl>eErCE~D%mRl_NlmT&;j=>2
z(cRi_B;7`(QTdWFtu++MAIA-!VhUP&O8@XM13GkikuC}iyWqX;>kRC({AwKBE!>;=
zBy_n(UI_6tvu8~N9~QaL?D}`jn4!nlN^8|fYh`Q}L(ni3TZ`A{pZD?{!NH{;p4aO`
zvw%7n9c$X-$NcCNfnOn95$-H6PZ|}tY0`&rKKwqbeBMJ3^88*o*cA?bIjfg^{W%AI
zmzl)b*g?*fD_v{|KnjI(@MbQiU~1I024bd3osuZe;+r`@L?VU2egza2*&L8Ic?WnD
zkD9{dl>jfNz4-;}4Z$5HuN;qEqq%xdjM_wqDia#>Kr
zwjDXcGxRDk0@P|yP*6W0QJx=p4<6J$xj4lxAP}|V+z{jFv**(#4xIsb3(I=tH~5JU
zSJ(u?@mFuy6z|?;!U@Od;pUM-GW(s@CQc9wl!1W(C;XyD4KyjbfieP%s+#;1e{ZwZloi
zY=J3`adRutZwG09fQbN^<_x1vNlC%Yb)LEi(wN|>Rt3CXm4ayZTRggj8quH7|FYfa
zWEfwT^XAl9UWapqMOVum`<|3HHTwSf!UNE@sM8x#weLRTt!aDi2y`EUW2){=iuMWw
zv+!pMSiV8_JAg{nq>G2z+G_6CH{2Pwrpf)HvFr;wAl=vd{SOILRVPdO1HnUUrD%A1
zmg(8=Qr5#A6%nDv`q52`(PZSYqSUtF9`0k|ziPv$T2@L=#>32YJElJ-2y4J+YO5$O}%7Z4V#PhDfn;HpYs!084R6
za*SF+>znQFxt|`l{usp9IOr6Z2U^&4XYP1c3^^}^3srrK&>;eWKYi!*Fy!O)P+4^i
zH9AJuTh*Lg`pE<2W&bTXx}?j$Z=D#o0@(p=ngBZUn{Xn-sCET7iZ!mCU}9S0Xi^j{9v~6JF3a;Y(Jte
zEH2(Wa4}KYwKli!nRL~H)l3gH?~nG{CD57_NqYn@(xPc*#=X9F^Jb_`bKCN9|4Nr?b?A
zaag^Y=SRg@NjJ_W0PlS^aB;l5bTxp#Em(PPa!i%>C#tN4g2%yq0ctG{ybI!weq7$#
zYr@(9KFM0_ifVrSx)J8@01%}c0h(Q&`&C1{zF*HN-f5YI&QaFp1(*Bidsb{_Ub$0@
zcfCfonN|5z);NL$nE2T&ZH;O-G%`{LKmv-JkkURcy{z`0Ya4tQIDn++0z5$%evDkU
zY@-}48=E@1GYb5y<`7b`@XM2e45;wKgBs5OwN4QU{C;sNLRu`?P#~)Yt@6
zg5VeGjJjXBK=xNh(U~KG^D3SbLO-gOm%IeT9rQRA9lL^XK~wvdOvO;cl0)|LdfdB+
zrHz`C!Q*>}KQWulHlJL2`(RLh2sfSLhXV3heZ9htlKadH%OEE`hi;v=kh|57vKpL`
zS%nAd$;;DgeP#z39C{zGB{1UqoOO`QQz1YDsGv}EVdtr?*1#2bp0Z;ZUi1cl3JmQ<
zhKIA??LBay9j7bZGSClNIc#E|Py#0EPO1QM!ap`AO|$=zbX
zf(8}W0FfC%p205Czz|)`d=If(b@JJo+R;3tY>xHoBY^`xfu;+dV>aAqk?a!y3yjRSCD2f{jAdpZ)D~a|-
zX68HL;*Y*x*mBzqsKizJ_=UwEZdEWW`s3<2CgnK7ohGq$D|QQ}yyGW%)x13e=UeUM
zSEMNYfhIW(skZQ0yA%Dz^Kt5cHCZs+y
z$tN6=qrDwyU6LBf-*Cm0EF|GHz4;|tlwk$4gZXyk8L^lN!QPB14To294IVlq#s+QKmELHnd(WxgCm`e@X
zkctcA4FDEh7G_-+5W=C%(7+|U>-lL_#UO^Fi9dh!N>@vZ8ck?0j#L=nGt|E!P+vd}
zQGoFx6^?L>2Eux%m1AU$T%_!~q>4s90K7sP$m+fS{8RJbX!iG#i&)7d_#=sv775pZ
z;M-6fM?+?2Cx6@a#8;UGu7K}A7*XOw5o3dscFW}s$2xS?(c
zmU%xkdH?|@pr9pSURG0(agp7jO6H}ChC`%f>|U4~&C@s_dSL8(6p$q=$V?`tr+1r}@PmvPaV)fJ6$uIsUNwWZ
zmKr!XD#^SP$JnEEH_~pxnVmgWEiWRX#i;7gQ+9~)=7~zLwYa4W_5sI=OTV?IF<^0g
zjqxxfxi~ky)y|^87~yBI)rm(k!%&PIQAB;Mba28mN>Ie{9HZ-ByVU}#-*u@llUDV<
z;U_F2275UX`;%p`sePy&gW%?!sk!C$^CO0*Y;0Dk)6lc93+nCPU$pMhU;}IB@aXVx
z2oaezUi{U%C%CcQUICjr;_4KX{+~WBFDa3L9@4Omg+BRS$Eg#TkML0z0nbYvC&tr2
zB4XyjL~2S8JUG+8Nk5GHP3@;g&5jnI!Jc{*YevU;qGcO{4z#m>5lSurN`K#_@wL=j
zi(78W(qv5$^qWG#@SHv7=68E%L7{EjxRC~Zzen>nhwkq^hAgq
zNdCU@h~sjX&QrIY0Jlw+_Mt;H5{z4lmd)bXbgdtHm^L3Md>5c~Vq5rm{!k$;o{S9v
zTs}_sKUfsqOqMmO(H|Q7d07dgG5DFeCD`qEIdndvBgqAK9~cWWh3sH&Z&jFw-+z9}
zCa4;U%7GKAS51I~fg5yljrEeS4fWOj(1OU&G&14_)izQ*?D|Xj$i4kFFyYF=s}s@y
z7(UrZD76G2GvI~y6(2n~ST&5*L^#7He3xf@Sp_%3Xy0-2EWo7H{Csu_|96*95|!rC
zFDH@Y>$W6$A9jwEJd*zV+$_e1gyxu*ih#=jhS302UB>n$FY@+d^W+ypB;cWJEdav_
z#=`iXo!YPNJyyKv2i4F
zmM53__(N{H$XrR);}1Vr9Q!T1=}TgLQ);`{`OVKnWa-a;3pTCel$G?_6!7_J)Q{|p
z7t=Q;V!SjZ?C=(qdw82<4#qjNQ?j~fQYs^a3z(7EkKJTrSV-hfUf?a?DnkjN|=
zMeH=}Qt3+TEDIjrn@E54u<=UKuGvp7UWty%8b9Pt*!nnV&F=V#fec6Ej#1xyArB@l
z&WmZ?$}gzJS-96+m+FY$h~_-;Ec@s^6_vlBC3b`KR@C;7HuFEiVyWn_
zs|{vG4WTatNiWb|URBS0y&)4&QRPy}#0g#-s%
zB9kCg+2t#0oJF~+
zY?Ft)EAT!HPYGTGqR0bb1v?p2Az}GvSbce$s?(**v9YlNuR;roj~w{tpMl$2C=?Eg
zq>1n>tIn*|^<9=JX{TlEu^cW=+p1)k(qj+r(Ut5EAjg>
zNU?2oY`LY^;dP4S$U%2e7LBrN@9B6()lY44x`5=V_`fWI7g|=Kb7)A8(K^9{z(4G6j|{n@0PW
zDCcG2Pp4GJ>Z_emV%UR*^rRi%95K)+>!!8#!|&)Z^G-^r^WTV5-9LjK>uEY9tO@{K
zk@B>5=lGL0iwj(+>63is{+T_I*=E^a?GM_A>+ST4y56O`sBOiCS
zn{&!JcF99V0aT>(e1DcCJnd3PY{A&0f_RQ*3~H;9DCuq6EIpu2I>c}-Q?lXl^>LZ$
z#ztAUZmWlC6;x;VXKWjNZvFl!{po4hqvo7Ox43L-cCtE{Vwz9Mss8yKE0wc-h>>0>
zp$_SvS5lN$GDqCr^GQGTlF!@`Kz<
z=Msjgq~}px554O26A4*+jg~En)13HfVL$8Cm<$$jMI;(p@&E0C1ABGV6G%rQX0gKJFKsE(%pn+g-j+$zQ-MO03-q?xh-fazk=6Bi1roG6`zI4J#gPMgEm@YuMX~P
z0PQn9MRmIUh)13?P8PrNjRhqL8&fs!ZB{+cF^_>)m9MR;l~(s>#BLaH2)k6c-|-dK
z$(oEu5(6`OHpllmrCINMVIfoPpoprn)c#LB&Lbae_P_?_P&ZF_
z-AUg7Gi@EHLiB3jv(V_RdBjCfM6@_vj_PpvpE`BQ0?`XIo|N)&u^|Sgfi9@bV{Az7
zE@7mY%l6-vUxn_o9z&agP%ZMHL37Bb+3kof_u1LJ$}3-*IG94hlcNP7rDLr@FEJk%p1
zsFkvIKf-7N&r2V_Q>Phhoq$h`Xx3MtfFC_!KYA-*U;*O8422268Ztehw+CLTFyJix
z=m=}kkFxXgGvUbaon+`p&|brxSoPih)RVc9Y|?iTSgzZ#R9If#@Oe1VPog*N9*qDB
z*?K_TOs}^1#d68_ySzJSFE3OmD0?hN#d`jnt#DMXSe_Hh@frHOtT(@ERoy35xuh!{
zPm|9c_^o~TFehoeE9OBH9x^fM`s@MNiH-t`22nDgygKj2Rt)g6#zF?>pVDuKzeh*%
zu}fJM6-kX0kGvetk}Jt=qfjDQ*ZJifG2i2DaUofhbAGP#N?Vn{yRP9O78o>pJh~lg
z$IovU;V0Jx=;{E{uP!b(AaZCiU@0&Ja8UO{tLwMs=Z6GxCHtM8m7f-pkc`7Kwa8
zn$Ix9K`e47-W{k%W42jMO%Tl&Sq?6vIi*?vHgRpi|As>Jgu)^pLa!(Ak+GI+@*26H
znUC=|J+6(!S)jXb9}~bl;{GA1R+Lg-)-i2sEUlaBzG^7vE#>(+xQC4WMoEWF#5cfU
zwZ(3bA{dlx15|G$>+e|PC$JmlxRM)3fGRA|WKi{B>>IQ5o`$0q>&t!X2Jny|EvJ(%
zbK_t3pw@*~4i2A)iXV@e(X!O^l>dI0hK~s+WF$CV0*67TcMWPMxl
ziyWWelZX(LWrN7ioR=`CGrQx6dp&BBOygr$dUrIA_AXoh=D5yh)}4~4;85TF#ci0m
zXUnEd9mO}C@52rD1XGY^`vX^-^nPJgXjZ3m*a#hI)A71H!G8%?F~J
zmjg%NFDs>M9P3IAh$-I8lR1#0oxPs7vj}DON!e;IvRW*wMW)sd}NKi8Z>{XG|te;CP_x0FBHJ
zH(pU4mfB=zp022i&cEDVhTZDu{~c9sbSvcZzwTV4&4(UJ?kO-oH&v3mzJAW_`d4`w
zrAI-gBAjUvZ#QT%sk!V}CsSv`0paI6t>a%SK)Uen?
zlj40_4L5)r|V?lPH?ngy-mBl;0`GYhe
zQ?FDiePbEI4OaN6^P8T^fz~R^o|&I4TYFPbq1I;pNm@7W!wvHihHu}O*12DooJ#iC
zqj37qUtxrn|1_Kp3yb5v&LzK1064-`DYmeLbg?S9H4)|tmsM8=Z&D42yzf>
z>4T!s7Z^P>_9rMRm|hI*ZBSpDT&;=`Pmt?6xmTb|An5gqgGNk@;7aHc8}9Frp-KHh
z4p}60J@3(zmN_<@iau`64=bkmvMO(z?>WV+wsn&dbGbaXH+yu3^acCqS87T?Cqz=C
zQ&H7o4Se@uI{*75*IlWn4l}b$qnZ4@Njp{F&Kyh`GSzE(cK9J*!OM*`AzfyjOh+;f
z4*;9pUFxK?GZrHLkN_%FTs%(QOg=}tp>f!qZZ#}&@sG*;nm#1;)w=4znkT$0dv9j8
z?(TGniFuZMSCR=pZ%XVf?*ANwh+EF`Hx*bZBFNUV`ax
z`}%G-x(n@kP{s`C=0g-oMw}>5MiNch$bY2iDiu$udao^q2zbmC
zr?Ymn`CR?47T~mLh2h;VvmKAlIweMIbl~~M9WgxG43{foX~l&LxkrS|%#5dI0`jg$
z>`gEZp`&Q-`{*@ul)u>c-(RA+c1}-at-R|dm%eV1l~0%MTUXh0zn_NUen|Pl_V=B`
zx+`n+hwFo_?o#dGvd)ht
z+_tXRtHjG9m`HL2#JUs;G)G$E`lmbYGSjd}TVsVhNoUF|S)&=$6r;`Wz27?P5wliD
zk^C$rxz$>^R!{7Lmnm7BSQba><41e9aEDD=jPrTs7!N~Dz3hJXIINHM|kvfH1Q
zvrIYf&-q_NuSZ6CQz(!Pp(ZP__bnMtHBi1FIeUqqiF|EUR03C_VEH^UCL91xB<_g6M@Xy@Szf9faR_{{orje35H`$PUmzUJlZ$!v1$
zx*Z=6-xLRAjFGz5cLe8AixIw&@JiZgtrQACkDih5#I^^YN5OHc2A=d>ece2>jchW=tZGwG3a@!-l`
ztJ-r%bg{SXh~1l8sdxC;V;-=pCeAYKk6iCCf|3X+OK;2IxbsJ5j7G8Pm}bNXQ<@G))?LI=;C
zhCsqIo^0B8J?+JP$M}ZV4Jl7fagFf*&^EQtau=Ir&m9TaGylrX{vaj!x(vzd$n2Fe
z$6Lx$n;MeldZU6XokO&GW`h^fp9}M@xf`l4mXT00&{gd(ugP=J30&67Vib1MSCAuK55
zcXPkTBKrILjZ_2gz{G#jJ4uLu;0n>Ef`6gmm*kp^+MgR)ja7hM}B`LIoxW`GO}VCG)R80(&ngSt<%q8D9EPp4oKy2Z%EmJn1RmaUQjP
zc-f0HJeZ)23WJTP;mJ6sz(K;sp?UoT@DKufT<2;GSO8YeTj2`MRF*)&s1EsLWn~?I
zNvtdg$?MmzV-zGckYPqv*6CmF3ID>Ons|_bn4Re8ikoB$|9X>OomX^_M&h#aky|U@
zAZDEK(y9!(8zPa(9_P{I?K?lD>TZh}j2iH*#g;tic=dMe4IjCgduu=tn3cIuK_gua
z>gx8`swWr+>d=u-wY0QUyL%K^{RD)0R`9ue{gC%_Rh|VdjI?U$6A?
z$A!LbsPa>K?Gpyn)1+uD|C*=jtujjQWsw9mH45$X%Ro9!imwh4^8w+c;CY1f5RFzi
zunR@y5`g?f?hk<=VL{+OqozPy7l4V2RG1H04PuRd*L(DX5TU9Q7!*+dBZK?o$1rzG
z0vOsA=sFqCmVwe?1b2j0WjWD*XZK}H{|&=vXO5HJlXPgLKD!i~M$`wOXApso24Wr{
zo%V{9Lof`-ZqX-Z9ac3T$j6~RQFiyfKp0)ZDpOF~hOishy+m+DS2T(Enu>8G6hFWK
z0~zt=wS-LYS@87nBY^TE8!i0vTad=tSYqLL9FwzcYROw
zv3miAJ&)ht*yX)3-{a*G<6Yj{8m_SVrG`0i?F(B!SWEvYX=B_#WoxskfcLeqjEVE-
ze$!C!!Im(T&Vu3$CipKj49@P~F){?)pDa|H!n4RaF)_Rdq=cb{UQD;N3Ozb>CFt~=
zd6ZF208I;mxE0cVzuOVZ0Ii6|LTiGG5)cqT`f8#a!1ODZ*^A~_(?A!9jWIPX%@ysb
zXyGo0=6`O#aOtS>t?KP4!5jqH%X99eGxx+?C&(;1zIK40NYBV16A#FzqA`Pyf)*$r
z1TjUeFNys0c^f)jp_siOmqy*u9qLXN4Ux{qX(faJ!{G8JgMy)SsVjeS4$WOMS48
z!P0wH=&PiznM8|U#zC87VS6KIs|Bw`oS4z)6Pj`De0m$B$A%~9+=*)@8MMH(Aej1f
zn9vjkk)v?H9B8lsWExLAOM`=-KOBk%OAJ^)AgC=?`G>!Ynh$(Lwh{~mf?2EV+H+34
zxk;=H)ffW_U3C7LHc=>da$8L}Pds+_*AdY~-wX&h#VC7Bu+(M`vSKpOmc4p<=j;S?
z(+$N6Fik6@L2=sobcOWJofUo7&_iKy*P?wUE(rn-0|Y}vbNGD|(seREfB@=mmtXf?
z4%u_m)|ax}_ieMyVbQgWM;U1YuLp@XNhMpP@Nld>f7~cP=Pb=J&0`um9Y=W!X7Q`RU=uh$I(vpjn+t${+xTyI!DYd#xIYvMD}bS
z-j(@?^RF?d5u6dI#Bq5{nPLL{z)B?8*dQ2tNR%%)t=-^_L8Xq$FJTXWm?wYdy`o9H
zOIYxk7Hfrr*tHnXtgn+nU=4;fw01E>LS;d69*&yd}GaLA_u-Q_Lkj=B~pBTBd97`uMO0ZtPKXVi^fw#4z8ioE*oW
zW!S2u$AGlE71P6$Z~fk77Q-hs{QyH6R)G>BqGgc+LPn
z$tB%R6|9ijYXgrUvnhb(uiBh&^`SkKm60ETe
zh+7HxTM+DnM9&22is!F6TruIGo^Wvf*l^X4B#KNN3#a?LVtbuJjI!yPAHgg?GEwty
zbflb+_f{Q##yfRCTxFX|MAz(N7a6;G^l14y$7AQWmAwp}QyR>BIwyv~&L?!Ytlpp&
z2`uk=eEc9VcLT8-q-mH{Ff&u=LlmH&=V!S>KWzVk$OH(6
z*r3o@gDmGDX$(14m}}{2`f1eV>`cMDvR1T&*eM-qU5^Os=SN9;Xgz2yeynjQH`~X+
zZw>Ypvisd-KYcyDI<(!yH}G`qUvXp{7|T5|=$(Uyr_p&CX)yoXFp|0}HSEb0KRjmy
z+1Ual)=hxn%fsa1L&lgSbi_0R^dG@+p^bX>sXpS*j1wkZt>B*6k`R|~R8i>~{18sA
z=4Yc%n9qVD7X?(5ZrkU7zyBtTerY#KyAMKl;)+;oG-i!&sxn$h+isl=Hx|;msro!B
zM&Q`uOK@iI?d&l{T9Kp?+)eb5L=$=c@Npk-k!XAw~0f+SDbXF++{46-+Zu9HOm@#9BvK6cm^Iv^)Z
zn>v$oPj26B{_TjLnP26Ooz}{Jr+5*Vo$Ua?!7qWU74Kl~0~KZwI_0ZhXo2(5jme3X
zPmWet_*G@`%vd)=oDEESI+-&cQ6T^f^9}jBpDZnQx58D}jfP^u^;Vkb+b`*7`a=>6
z!|2|OxAejz>DXvG4{p2fDTxuIWFPn`Bs1aof%)XQ(zA`A^~n4p
z@ZPYz&|o|{4YVNnfOwYH{rM06?FrbMco<=L!Tk)l>iPJH`#scII75^1N}r{;}aw|in7g7m$?}PvMVclt4u$~
zC@npm7J^fc3IY4#$GtoEE3apRtQR*I#F3ib?IJchp)S8`972aVSfc)6h^VyA>5OOE
zY|umzCXcuyEP2W3B(wz3n`)St+&*IY9Cojj+>h&i74}LE
z%=ke4z$>kJAj4ZN6WLs}GdDQPJa4A!{NI2h7NjMNTZyWR3EEQp
zdSO-7CpA2W9qVliQ(zdya)WLc<@uN(`=7LA$cQ=Qv~->a9CFGH=(DvS|3;x)7ulg@
zBTzV07gcsg=a{2c*{9e8IgN6>EJVZ#DYvnNhgU8bb7Vtp423Ivj1nAQ=A4whnCc
z>XzT}W-}3(MMTnZRP-&>^J$HQZbp&j4_tVojLbD@gC?7`Wra^tDqY8Wqi!)~&G>ko
zlk7!}Wm(!iiN1E{^o^$lZ!(~-*AQ~4n2yy-p)^0rx_{rb^B)>Xd|wAvyzX1?(=T%Q*=e)X2^roC=y(wF%51Pf
z@adXOtQvl^L*>Umy&oU`@@2A_L)on0Ir5{zV_yIXU?3(y$&;q!;A_{9CQ9*|FdY$b
z2l@#zyyQT1rP~*#T=U9sm{%o?^OI|)z@6ytnl>z?3Wc?209rXsxT;YGRm-q^6dts#
zsg%wQ_j1$YE}QwV4pUcfYZC)jXI*L;wdSQyR5`DO*)>p%^0%{;%a*l4oN5N$752rK
z2xGSuL5%m7wJW>-t(#ed9>(tgvbB@v$FL35({rlpYHbTOGutM24<8jzy>_}ftrE`X}n8jwFY@dNj_QS6Lq($q=Xw$K@hz@+Pb0k8?|et<_8+q9gT)n
z7McVUdZ5rdzPh3+B-93S3Bo)A?)W`%pFv2Zh_)P^9Z?un_1ejQLM!KQu+{yA>KVym
z6IPhiQPTOC{`1c&%sgjl&lw&h!B(PK1SIe`UIaVrP?xSar28wD#MK`AZAL;AeH65T
zGAx6S?lJr=SZ<;9!Sc`$iAlx*lR+x@vAGKgr5$4)(9Mu3FjzL&4k+lkyeBwb_}OjY
z^yeM;X>s#Ax8d!x7Ot};ia|O;y4TvPP6P<{p_H8fC-A9FU%ei=3gd<-NT--qsx8EB
z0pjD}U_1o6I8!o|2ZHN8pnZt58TkeTQ>Zk*C+vs##TIY_vvzHXi;Me&YFF^r8E+vF{;!P
z2{h*BO+?o)z@lmBNkG4zt6&Sj|zJo|;C=U)K|@xT*j=iR%}
zz@{;ThzN<4lu9+PS7II-X$PJzFI^(k80uKsk;e~^C9J@{vrc
zpy9yv_UGKpm0EIQ=ND!m^C0@Fi8mQ>0#`K|OaG>v&Az~Ov-$ZlXizg>u|Y_p4XqBL
zQBi#$KSKnLheYwQ#@SHF!Qc@)6qv-3iiw>KRpYV3sRcj@P*X+${!q$NI`k2P=Y(RL
zTrhKjFrZP<5m8aQF(d)qiErDbLR?X1LfB)3CaJPuQYAba#Nl^XzZSI%T