diff --git a/docs/plans/2026-05-15-post-attendance-flow-v2-design.md b/docs/plans/2026-05-15-post-attendance-flow-v2-design.md
new file mode 100644
index 0000000..abe2139
--- /dev/null
+++ b/docs/plans/2026-05-15-post-attendance-flow-v2-design.md
@@ -0,0 +1,203 @@
+# Post-Attendance Flow v2 — Design
+
+**Date:** 15 May 2026
+**Status:** Approved by Konrad on 15 May 2026; ready for implementation plan.
+**Branch:** `ai-dev`. **NOT to be pushed/deployed until Konrad confirms it works locally.**
+
+## Goal (one sentence)
+
+Replace the forced auto-redirect into the Site Report form after every
+attendance submit with three explicit, clearly-prioritised choices —
+"just log work", "log work + site journal", "log work + absences" — and
+add a parallel "save + add absences" path on the site-journal page,
+while renaming the user-facing vocabulary to "Site Journal" to free up
+"Journal" for the (parked) voice-transcript feature.
+
+## Why
+
+Phase A.1 shipped a two-step flow: attendance submit → forced redirect
+to the SiteReport form (with a Skip link). In real use Konrad found the
+forced redirect intrusive — most days he just wants to log attendance
+and be done. The fix is to make the site-journal step (and the absences
+step) explicit opt-in buttons rather than a mandatory interstitial.
+
+## Decisions locked in (from the brainstorm)
+
+| # | Question | Decision |
+|---|----------|----------|
+| 1 | "Journal" naming collision (parked voice JournalEntry vs the structured SiteReport form) | Rename the SiteReport-the-page to **"Site Journal"** in all UI text. Model/view/URL stay `SiteReport`/`site_report_*` in code (Path-A display-only rename, zero migration). The parked voice feature will be renamed (e.g. "Voice Notes") so it doesn't collide. |
+| 2 | Where does plain "Log Work" land now? | **Dashboard** (home) + the existing green "work log(s) created" toast. No more forced SiteReport redirect. |
+| 3 | Button structure | **Approach C** — exactly the 3 explicit buttons Konrad asked for, but with deliberate visual hierarchy (primary "Log Work" + two secondary "+ …" buttons) so 3 buttons don't feel like a wall. |
+| 4 | End of the "+ Add Absences" chain | The absences form's own buttons (Log Absences → list, Cancel) are the natural end. No extra chaining. |
+
+## § 1 — Vocabulary rename (display-only, zero migration)
+
+User-facing text changes from "Site Report" / "Log Today's Work" →
+**"Site Journal"**:
+
+- `core/templates/core/site_report_edit.html` — `
` "Log Today's
+ Work" → "Site Journal"; save button "Save Site Report" → "Save Site
+ Journal"; `{% block title %}` text.
+- `core/templates/core/site_report_detail.html` — heading + ``.
+- `core/templates/core/work_history.html` — the clipboard-icon tooltip
+ / link title text that references "site report".
+- Success-toast string in `core/views.py::site_report_edit` — "Site
+ report saved …" → "Site journal saved …".
+
+**Unchanged in code (Path-A pattern, per CLAUDE.md "UI-vs-DB naming
+drift"):** `SiteReport` model, `site_report_edit` /
+`site_report_detail` views, `/site-report//edit/` + `/site-report/
+/` URLs, the `work_log.site_report` related-name, `SiteReportForm`,
+`core/site_report_schema.py`, all existing tests. Only user-visible
+strings move.
+
+**Parked-work doc note:** add a line under the Backburner section that
+the future voice-transcript feature must NOT be called "Journal" (the
+name is now taken by the site-progress form) — suggest "Voice Notes".
+
+## § 2 — Attendance form: 3 buttons, clear hierarchy
+
+`/attendance/log/` submit block (top → bottom, Konrad's specified order):
+
+| Button label | Bootstrap style | `next_action` value | Redirect on success |
+|---|---|---|---|
+| **Log Work** | `btn btn-lg btn-accent` (primary, orange) | `log_only` | `redirect('home')` + toast |
+| **Log Work + Site Journal** | `btn btn-lg btn-outline-secondary` | `log_journal` *(NEW)* | `redirect('site_report_edit', work_log_id=)` |
+| **Log Work + Add Absences** | `btn btn-lg btn-outline-secondary` | `log_absences` | `/absences/log/?date=&team=&project=` (unchanged) |
+
+- The primary orange "Log Work" anchors the eye — the common case.
+- The two `+ …` buttons are visually secondary (outline) — opt-in.
+- `log_only` changes its redirect target from SiteReport → home.
+ This is the behavioural reversal of Phase A.1's forced redirect.
+- `log_journal` is new; it does exactly what `log_only` used to do
+ (go to the site-journal form for the last-created WorkLog).
+- `log_absences` is untouched (Round C).
+- The conflict-resolution re-render already passes `next_action`
+ through via the `form.data.items` loop (Round C, commit `8c749f3`).
+ `log_journal` rides those same rails for free — no extra work, but
+ needs a regression test.
+
+## § 3 — Site Journal page: 3 actions, same hierarchy
+
+`/site-report//edit/` action row:
+
+| Action label | Style | Behaviour |
+|---|---|---|
+| **Skip** | quiet `btn btn-outline-secondary` (or text link) | → `home`, nothing saved (unchanged) |
+| **Save Site Journal** | `btn btn-accent` (primary) | Save → `home` + toast (unchanged destination) |
+| **Save Site Journal + Add Absences** | `btn btn-outline-secondary` | Save → `/absences/log/?date=&team=&project=` prefilled from the WorkLog |
+
+- Mirror of the attendance form's hierarchy.
+- The absence prefill query string is built from `work_log.date`,
+ `work_log.team_id`, `work_log.project_id` — the view already
+ `select_related('project', 'team', 'supervisor')`s the work_log, so
+ no new query. Identical query-string construction to the attendance
+ form's `log_absences` branch (DRY: consider a tiny shared helper
+ `_absence_prefill_qs(work_log)` but YAGNI — two call sites, ~3 lines
+ each; decide during implementation).
+- New submit button carries `name="next_action" value="save_absences"`.
+ The view reads it after a successful `form.save()`.
+
+## § 4 — View changes
+
+### `core/views.py::attendance_log` (POST success branch)
+
+Current Round C logic: `next_action == 'log_absences'` → absences
+prefill; else → `redirect('site_report_edit', …)`.
+
+New logic:
+- `next_action == 'log_absences'` → absences prefill (unchanged)
+- `next_action == 'log_journal'` → `redirect('site_report_edit',
+ work_log_id=created_log_ids[-1])` (what the old default did)
+- else (`log_only`, missing, or anything unrecognised) →
+ `redirect('home')` + success toast
+
+### `core/views.py::site_report_edit` (POST success branch)
+
+Current: always `redirect('home')` after `instance.save()`.
+
+New:
+```python
+instance.save()
+messages.success(request, f"Site journal saved for {work_log.project.name} on {work_log.date:%d %b %Y}.")
+if request.POST.get('next_action') == 'save_absences':
+ from urllib.parse import urlencode
+ params = {'date': work_log.date.isoformat()}
+ if work_log.team_id:
+ params['team'] = work_log.team_id
+ if work_log.project_id:
+ params['project'] = work_log.project_id
+ return redirect(f"{reverse('absence_log')}?{urlencode(params)}")
+return redirect('home')
+```
+
+(Exact variable names verified against the live view during planning.)
+
+## Tests (~5, in `core/tests.py`)
+
+1. `attendance_log` POST `next_action=log_only` → 302 to `/` (home),
+ NOT to `/site-report/…`. (Regression — this reverses Phase A.1.)
+2. `attendance_log` POST `next_action=log_journal` → 302 to
+ `/site-report//edit/`.
+3. `attendance_log` POST `next_action=log_absences` → 302 to
+ `/absences/log/?...` (existing test, confirm still green).
+4. `site_report_edit` POST default (`next_action` absent) → saves +
+ 302 to `/` (home).
+5. `site_report_edit` POST `next_action=save_absences` → saves +
+ 302 to `/absences/log/?date=…&team=…&project=…`.
+6. Conflict-resolution path carries `next_action=log_journal` through
+ to the final redirect (extend the existing Round C conflict test).
+
+Update any existing test that asserted attendance submit redirects to
+the site report by default — that contract is intentionally changing.
+
+## Files touched
+
+| File | Change |
+|---|---|
+| `core/templates/core/attendance_log.html` | +1 button (`log_journal`), restyle 3 buttons into primary/secondary hierarchy |
+| `core/templates/core/site_report_edit.html` | text → "Site Journal"; +1 submit button (`save_absences`) |
+| `core/templates/core/site_report_detail.html` | heading/title text → "Site Journal" |
+| `core/templates/core/work_history.html` | clipboard tooltip text → "site journal" |
+| `core/views.py::attendance_log` | 3-way `next_action` branch (log_only→home, log_journal→site report, log_absences→absences) |
+| `core/views.py::site_report_edit` | `next_action=save_absences` branch + toast text |
+| `core/tests.py` | ~6 new/updated tests |
+| `docs/plans/parked-work.md` | Backburner note: future voice feature ≠ "Journal" |
+| `CLAUDE.md` | Update the SiteReport line + URL-routes note: UI label is "Site Journal", model stays `SiteReport` (another Path-A entry) |
+
+**No model / migration / URL / dependency changes.** ~120 LOC incl.
+tests. Pure flow + display change.
+
+## Out of scope (deliberately)
+
+- No change to the SiteReport model, schema, or `site_report_schema.py`.
+- No change to the absences feature itself (just the prefill entry point).
+- No actual building of the voice-transcript "Voice Notes" feature —
+ still backburnered; this only reserves the name.
+- No "what next?" interstitial panel (rejected in Q2 — Konrad chose a
+ plain dashboard landing for `log_only`).
+
+## Verification (manual, local — Konrad)
+
+1. `/attendance/log/` → submit with **Log Work** → lands on dashboard
+ with toast, NOT the site-journal form.
+2. Submit with **Log Work + Site Journal** → lands on the Site Journal
+ form (titled "Site Journal").
+3. Submit with **Log Work + Add Absences** → lands on `/absences/log/`
+ prefilled (unchanged).
+4. On the Site Journal form, **Save Site Journal** → dashboard + toast.
+5. **Save Site Journal + Add Absences** → `/absences/log/` prefilled
+ with the same date/team/project.
+6. Trigger an attendance conflict while having clicked "Log Work +
+ Site Journal" → resolve it → still lands on the Site Journal form.
+7. Full suite green (`USE_SQLITE=true … manage.py test core.tests`).
+
+Then — and only then — Konrad decides whether to push to `ai-dev` +
+deploy.
+
+## Branch / deploy
+
+Build on `ai-dev`. **Do NOT push to origin or deploy** until Konrad
+has run the local verification above and explicitly approves. This is
+a UX-flow change to a daily-use path — it warrants a hands-on local
+check before it reaches production.