Estimate: 60m · Depends on: 6.12.1, 6.12.4, 6.12.6, 6.12.7
Why this exists (planning gap, found running 6.12.10): 6.12.6 shipped the upvote + public-request COMMENT backend (POST /api/public-requests/[id]/upvote and POST /api/public-requests/[id]/comments), and 6.12.7 added the roadmap upvote control (PublicRoadmapVote) — but there is NO public request DETAIL surface and NO comment UI anywhere (PublicRoadmap’s own comment notes: "there is no public request DETAIL route yet; that surface, design Panel 5, is unbuilt"; submitted roadmap cards are plain text with no link). So a public viewer cannot open a request, read its comments, or comment, and the e2e (6.12.10 step 3 "add a comment on that public request → it appears") has no real UI to drive. This card builds the missing public request detail + comment UI per the 6.12.1 Panel 4/5 design.
app/(public)/ for a public request (reached from the roadmap cards — repoint PublicRoadmap titles/cards to it — and from the 6.12.11 dedupe candidates), gated by the same anonymous-read browse check the other public tabs use (non-public / unknown → 404-not-403). It renders the request title + kind + status + body through the public projection (no internal field leaks — reuse the 6.12.4 read shape).PublicRoadmapVote control (one vote per account, toggle, sign-in-to-act when logged out) so the detail and the roadmap share one upvote affordance.isPublic comments from 6.12.6 — the work item’s INTERNAL comments stay hidden by the projection) and a composer that POSTs to /api/public-requests/[id]/comments ({ bodyMd } → 201) for a signed-in account; a logged-out viewer sees the sign-in-to-act prompt on the composer. New comment appears on success (the composer fires from inside the thread island — optimistic local insert / authoritative refetch, per the page-state-after-mutation rule; no whole-tree refresh).publicProjectsService / publicRequestsService layer if one isn’t already exposed) — the upvote + comment WRITES reuse the shipped 6.12.6 routes. Stay 4-layer; design-compliant (ONLY shipped components/ui/* + --el-* / [data-display-style] tokens).PublicRoadmapVote: toggle, count, already-voted state, sign-in-to-act when logged out) and the public comment thread (only isPublic comments; internal comments never present).--el-* + [data-display-style] tokens + shipped components/ui/*; matches the 6.12.1 Panel 4/5 design; 4-layer respected (public-projection read in the service/repository; the upvote/comment writes reuse the shipped 6.12.6 routes; no raw Prisma in the route).design/public-projects/.app/api/public-requests/[id]/upvote/route.ts (POST → { voted, voteCount }) + app/api/public-requests/[id]/comments/route.ts (POST { bodyMd } → 201 CommentDTO).app/(public)/_components/PublicRoadmap.tsx (repoint the card links) + PublicRoadmapVote.tsx (reuse the upvote control) + the 6.12.4 public projection (lib/services/publicProjectsService.ts, lib/dto/publicProjects.ts).motir-core/CLAUDE.md § 4-layer + § colour/shape tokens + § page-state-after-mutation (client-island refetch).