The public portal page — /portal/:slug, no authentication, no
internal API access: everything renders from Portal.public_view/1's
whitelisted DTO (panel #5), and the submit path runs the full guard
chain inside handle_event (panel #2 — plug-level limits never see
LiveView events).
Every failure mode — unknown slug, disabled extension, disabled
capability, rotation while mounted — renders the SAME unavailable
state (panel #11), and a :portal_rotated broadcast downgrades live
sessions immediately (panel #7). Content renders through HEEx escaping
only — portal-sourced text is plain text at every egress (panel #4).