diff --git a/.planning/research/v1427-r3c-mobile-medications.md b/.planning/research/v1427-r3c-mobile-medications.md
new file mode 100644
index 000000000..28744c728
--- /dev/null
+++ b/.planning/research/v1427-r3c-mobile-medications.md
@@ -0,0 +1,189 @@
+---
+file: .planning/research/v1427-r3c-mobile-medications.md
+purpose: Mobile capability audit — medications surface (list, form, schedule editor, drug-level chart, therapy timeline)
+created: 2026-05-15
+auditor: MA5
+---
+
+# Mobile audit — medications surface
+
+## Summary
+
+Reviewed 12 components across `/medications` and `/medications/[id]/history` plus the medication form, schedule editor, DrugLevelChart standalone, three GLP-1 detail sections (Scheduling, Titration, SideEffects), Inventory disclosure, intake history (table + mobile cards), and three modal dialogs (IntakeImport, ApiEndpoint, PhaseConfig). Found **18 issues**: 3 Critical, 6 High, 6 Medium, 3 Low. Headline pattern: the GLP-1 surface (well-iterated since v1.4.25 W4d) is mobile-aware (44 pt tap targets, mobile cards, `touch-pan-y`), but the schedule editor's day grid breaks at 320 px, three dialogs ignore the global `max-w-[calc(100%-2rem)]` rule, the DrugLevelChart standalone has a broken YAxis label, and several action rows (intake table, side-effect delete, inventory pen actions) ship 28-32 pt icon buttons that fall below the WCAG 2.5.5 floor. No bottom-sheet primitive is used anywhere on the surface — every entry point is a centred dialog.
+
+## Findings
+
+### F1 — Schedule day-of-week row overflows / squishes at 320 px
+- Severity: Critical
+- Axis: visual
+- File: `src/components/medications/medication-form.tsx:869-903`
+- Symptom: The advanced schedule editor renders the daily-toggle button (`min-w-24` = 96 px) plus seven weekday buttons (`flex-1`) in one `flex w-full gap-1` row. At 320 px viewport minus dialog padding (≈ 288 px usable), the seven weekday buttons each get ≈ 27 px width and the labels (`Mo`/`Di`/…) crowd against each other; on iOS Safari with translated labels (`Mo`, `Di`, `Mi`, `Do`, `Fr`, `Sa`, `So`) the row is borderline; with the umlauts on `Mär`/`Mai`-style labels in other contexts the row already wraps badly.
+- Evidence: 96 px (Daily) + 7 × 27 px + 6 × 4 px (gap) ≈ 288 px. The weekday buttons are min-h-11 (44 pt) tall but only ~27 px wide — fails the WCAG 2.5.5 width axis.
+- Recommended fix: Switch to `grid grid-cols-7` for the weekday buttons on mobile, with the "Daily" button on its own row above (`grid grid-cols-1 sm:grid-cols-[6rem_1fr]`). Match the existing `intervalWeeks` grid pattern at line 845.
+- Effort: S
+
+### F2 — GLP-1 weekly preset day row has the same squish at 320 px
+- Severity: High
+- Axis: visual
+- File: `src/components/medications/medication-form.tsx:653-674`
+- Symptom: The weekly-cadence preset renders seven weekday buttons in a `flex w-full gap-1` row inside the form dialog. Same arithmetic as F1 — each button is ≈ 36 px (no leading "Daily" button) but the column still gets a 16 px left+right inner padding from the wrapping `p-3.5` card. Visually OK on 375 px+ but cramped at 320 px.
+- Evidence: Tailwind `gap-1` = 4 px. 7 buttons × 36 px + 6 × 4 px = 276 px, fits, but with iOS Safari's safe-area insets removed the column gets ~256 px leaving ~32 px per button.
+- Recommended fix: Same pattern as F1 — `grid grid-cols-7 gap-1`. Drop `flex w-full` so the buttons size evenly under the grid math.
+- Effort: S
+
+### F3 — DrugLevelChart YAxis label rendered in `width={1}` column — never visible
+- Severity: High
+- Axis: code
+- File: `src/components/medications/DrugLevelChart.tsx:549-563`
+- Symptom: The YAxis is configured `width={1}` (so the chart area has no left gutter), but the same axis sets `label={{ value: axisLabel, position: "insideLeft", angle: -90 }}`. Recharts paints the label inside the 1-px wide column; the SVG label is effectively clipped and invisible. The axis caption above the chart body (line 485-490) is what users actually read; the SVG label is dead code that bloats the SSR snapshot.
+- Evidence: Recharts `width` on YAxis governs the gutter the label paints into. `width={1}` collapses that gutter. The `axis-caption` `
` above the chart is the working label.
+- Recommended fix: Drop the `label={…}` prop from `` entirely; keep the visible `
` only. Same applies to the `` child of `` (line 535-544) — empty `` element with no `value` / `children`, also dead code.
+- Effort: S
+
+### F4 — Three dialogs lack the standard `sm:max-w-md` cap and rely on the v4 default
+- Severity: High
+- Axis: visual
+- File: `src/components/medications/SideEffectsSection.tsx:334`, `src/components/medications/intake-history-list.tsx:535,678`, `src/components/medications/inventory-section.tsx:434`, `src/app/medications/page.tsx:261,423,667`
+- Symptom: Most medication dialogs set `sm:max-w-md` or `sm:max-w-lg` — good. Two do not: the intake create/edit `` (lines 535 & 678) ships with the default `sm:max-w-lg` from `dialog.tsx:64`. The InventorySection add-pen dialog (line 434) likewise. On large desktop these become unnecessarily wide for the 3-field form; on narrow mobile the global `max-w-[calc(100%-2rem)]` saves them. Consistency-wise the medications surface is split.
+- Evidence: Grep across medication dialogs — only some carry `className="sm:max-w-md"`.
+- Recommended fix: Add `className="sm:max-w-md"` (or `sm:max-w-lg` where the schedule grid earns the extra width) to every medication `` for consistency. Document the rule in a comment on `dialog.tsx`.
+- Effort: S
+
+### F5 — Intake history "Mobile cards" use 32-pt edit/delete tap targets
+- Severity: High
+- Axis: visual
+- File: `src/components/medications/intake-history-list.tsx:482-497, 433-449, 805-812`
+- Symptom: The mobile-card view (`md:hidden` block at line 458) shows edit + delete icon buttons at `h-8 w-8` (32 px). Below the WCAG 2.5.5 44 px minimum. The desktop-only table uses the same 32 px sizes — acceptable for mouse, but the `` is shared between the desktop table cell and the mobile card row, so the mobile path inherits the wrong size.
+- Evidence: `medication-card.tsx` raised the analogous icon buttons to `min-h-11 min-w-11` in v1.4.15 phase-A5 (see comment line 396-399). The intake history surface skipped the same fix.
+- Recommended fix: Pass a `size` prop into `` or split the desktop/mobile renderers so the mobile card uses `min-h-11 min-w-11`. The edit button on the mobile card path (line 486) similarly needs `min-h-11 min-w-11`.
+- Effort: S
+
+### F6 — SideEffects delete button is 28 pt (h-7 w-7)
+- Severity: High
+- Axis: visual
+- File: `src/components/medications/SideEffectsSection.tsx:308-326`
+- Symptom: The per-entry delete button uses `h-7 w-7` (28 pt). Below WCAG 2.5.5. The aria-label is present, but the touch target is dangerous next to long notes — a thumb hit on the entry body is one column away.
+- Evidence: 28 px < 44 px floor. The new W19d UI shipped this in v1.4.25 W19d but does not match the v1.4.15-era 44 pt rule applied elsewhere.
+- Recommended fix: Bump to `min-h-11 min-w-11`; keep the inner icon at `h-3.5 w-3.5` for visual density.
+- Effort: S
+
+### F7 — Inventory section per-pen action buttons are 28 pt
+- Severity: High
+- Axis: visual
+- File: `src/components/medications/inventory-section.tsx:332-362, 405-414`
+- Symptom: "Mark as in use" / "Mark as used up" buttons are `h-7 px-2 text-[10px]` (28 pt tall). The 10 px font is also below the 11 px minimum the rest of the surface targets. The trash button on the "past pens" sub-list is `h-6 w-6` (24 pt) — even smaller, below the WCAG 2.5.8 24 px floor.
+- Evidence: Lines 332-362 (live items) + 405-414 (past pens delete).
+- Recommended fix: Live actions → `min-h-11 px-2.5 text-xs`. Past-pen delete → `min-h-11 min-w-11` icon button (the destructive ghost variant already exists on `medication-card.tsx`).
+- Effort: S
+
+### F8 — Schedule input height-pinning fights system font size on iOS
+- Severity: Medium
+- Axis: code
+- File: `src/components/medications/medication-form.tsx:781, 799, 813, 825`
+- Symptom: Each per-schedule input ships `className="h-11 text-xs md:text-xs"`. iOS Safari triggers an automatic zoom when an `` font-size is < 16 px on focus. The schedule inputs are 12 px (`text-xs`), so tapping any field on iOS Safari triggers a zoom-and-scroll that is jarring inside the modal.
+- Evidence: WebKit policy: any focusable text input below 16 px font-size triggers a viewport zoom. Same applies to the doseAmount input on the form (line 610 — uses default `Input` which is `text-sm` = 14 px → also zooms).
+- Recommended fix: Use `text-base` (16 px) on focusable inputs inside dialogs, or apply `text-sm @sm:text-xs` (the v4 container-query pattern). The codebase already uses `text-base` on inputs elsewhere — bring the schedule inputs in line.
+- Effort: M
+
+### F9 — IntakeImport dialog lacks `max-h-[90vh] overflow-y-auto`
+- Severity: Medium
+- Axis: visual
+- File: `src/app/medications/page.tsx:423`
+- Symptom: The create/edit medication dialog (line 261) caps height at `max-h-[90vh] overflow-y-auto`. The IntakeImport (line 423) and ApiEndpoint (line 667) dialogs do not. On 320 × 568 mobile viewports (iPhone SE landscape, smallest active iOS class), the import dialog's textarea (`rows={8}`) + JSON sample block overflows behind the on-screen keyboard with no scroll.
+- Evidence: `` — no max-h. Radix Dialog does not cap height by default.
+- Recommended fix: Apply the same `className="max-h-[90vh] overflow-y-auto sm:max-w-lg"` to both dialogs. Better: lift the cap into the shared `` defaults via a Tailwind plugin or document the rule.
+- Effort: S
+
+### F10 — Therapy timeline (Titration step list) wraps cells with 7-rem `min-w-`
+- Severity: Medium
+- Axis: visual
+- File: `src/components/medications/TitrationSection.tsx:152`
+- Symptom: Each ladder step is `flex flex-1 flex-col rounded-md border px-2.5 py-2 sm:min-w-[7rem]`. The `sm:` prefix means the `min-w-[7rem]` only applies at `sm` and above — so at 320-414 px the cells use only `flex-1` and stack vertically (`flex-col gap-2 sm:flex-row sm:flex-wrap`). That works. **But** on 768 px (iPad portrait inner tablet column) the steps wrap into rows of 3 because 7 rem × 3 + gaps = ~22 rem, then the 4th step wraps below alone, breaking the "horizontal ladder" reading. Also: at the 414-px to 640-px range the chevron continuation between steps is implicit (no visual connector) — readers see disconnected cards.
+- Evidence: `flex flex-1 … sm:min-w-[7rem]` — the breakpoint cliff is at `sm` (640 px). Between 640 and 768 the row wraps awkwardly.
+- Recommended fix: Either (a) keep `flex-col` until `md` (768) so iPad-portrait gets the vertical ladder same as mobile, or (b) replace the implicit "ladder" with a real visual connector (a left-side rail with step dots) that scales gracefully. Option (a) is the lower-effort patch.
+- Effort: M
+
+### F11 — SchedulingSection cadence grid wraps cells with 44×44 tap targets, but cells crowd at 320 px
+- Severity: Medium
+- Axis: visual
+- File: `src/components/medications/SchedulingSection.tsx:194-226`
+- Symptom: The 30-day cadence timeline renders `