---
path: /domains/veritas/newsletter
surface: customer
domain: veritas
auth: signed-in
source: apps/oshun/web/src/app/domains/veritas/newsletter/page.tsx
status: walked
last_walked: >
  2026-05-29 automated runtime walk (Playwright headless) — render, /v1 data
  (2xx), console/page-errors, expected content, screenshot verified; live
  screen-reader, touch, offline, and telemetry-delivery checks pending a manual
  AT pass. Evidence: WALKTHROUGH/results/runtime-sweep-2026-05-29.md. 2026-06-28
  Codex Newsletter Builder addendum — authenticated template selection, keyboard
  close, editor section expansion/reorder/remove/add, edited email details,
  preview stats/render, send-preview state, export affordances, reduced motion,
  standalone PWA restore, offline mobile use, and horizontal overflow checks are
  covered by the E2E evidence below. 2026-06-30 Codex export addendum — HTML
  export now generates a standalone newsletter document and copies it to the
  clipboard with a download fallback, PDF export invokes the browser print
  pipeline against the rendered preview, and both paths are covered by the E2E
  evidence below.
---

# Newsletter Builder · Veritas

## Purpose

The Veritas Newsletter Builder is a full-screen, fixture-backed editor for
assembling truth digests. A signed-in user chooses a newsletter template, edits
subject/preheader details, reviews and rearranges local section content, adds
section types, previews the rendered email, and triggers a simulated preview
send. From preview, the user can also copy/download a standalone HTML export or
open the browser print flow for PDF output.

## Entry Points

- **Direct URL / bookmark** — `/domains/veritas/newsletter` (auth required)
- **`/domains/veritas` index** — internal Veritas tool grid
- **Shell navigation history** — opening after `/library` lets the Close control
  return with `router.back()`

## Layout Regions

`page.tsx` is a client route that renders an `sr-only` `<h1>` ("Newsletter
Builder · Veritas · OSHUN") and mounts
`<VeritasNewsletterBuilder onClose={() => router.back()} />`.

- **Overlay root**: `[data-veritas-newsletter-builder]` with current
  `data-veritas-newsletter-view`, selected template, template/section/item
  counts, send state, sent state, and reduced-motion state.
- **Header**: `[data-veritas-newsletter-header]`, title, tablist
  `[data-veritas-newsletter-tabs]`, view tabs, and
  `[data-veritas-newsletter-close]`.
- **Templates view**: `[data-veritas-newsletter-templates-view]` with template
  cards from `SAMPLE_NEWSLETTER_TEMPLATES`. Cards are keyboardable and expose
  frequency/section counts.
- **Editor view**: `[data-veritas-newsletter-editor-view]` with Back/Preview
  actions, subject and preheader inputs, section editor rows, and add-section
  controls.
- **Preview view**: `[data-veritas-newsletter-preview-view]` with Back to
  Editor, Send Preview state, stats, rendered email preview, and HTML/PDF export
  controls.

## States

- [x] **Authenticated render** — route opens through the signed-in shell and
      renders `[data-veritas-newsletter-builder]`.
- [x] **Templates populated** — template-card count matches
      `SAMPLE_NEWSLETTER_TEMPLATES`.
- [x] **Templates with no selection** — `editor` and `preview` tabs are disabled
      until a template is selected.
- [x] **Template selected** — selecting a card seeds subject, preheader, and
      section state from the template, then switches to editor view.
- [x] **Editor populated** — section count and item count match the selected
      template fixture.
- [x] **Section expanded** — expanded rows reveal content, item headlines,
      verdict/source/confidence metadata, and local trust labels.
- [x] **Section reordered / removed / added** — move, remove, and add-section
      actions update local section order/count and the root state attributes.
- [x] **Preview populated** — preview stats and rendered email sections reflect
      the current editor state, including edited preheader text.
- [x] **Send preview pending / sent** — Send Preview flips sending state, then
      shows the sent badge after the local timer completes.
- [x] **HTML export copied / downloaded** — HTML export generates a standalone
      document from the active draft, writes it to the clipboard when available,
      falls back to a `.html` download, and records export state through
      `[data-veritas-newsletter-export-status]`.
- [x] **PDF print requested** — PDF export marks `pdf-print-requested` state and
      invokes the browser print pipeline with print CSS scoped to the rendered
      preview panel.
- [x] **Offline** — standalone mobile test switches the browser context offline
      and still selects a template, edits/expands sections, previews, and sends
      from local fixture state.
- [x] **Standalone PWA** — `mockStandaloneLaunch()` restores directly into the
      route from `/?surface=pwa`.
- [x] **Reduced motion** — template/section/preview animations collapse to
      `none` under `prefers-reduced-motion`.
- [x] **Mobile horizontal overflow** — standalone/offline test asserts no
      document overflow at 390×844.

## Interactions

### Header

- [x] **Close** — `[data-veritas-newsletter-close]` has accessible name "Close
      Newsletter Builder", a 44×44 target, keyboard activation, and returns to
      `/library` in the desktop path.
- [x] **Tabs** — `templates`, `editor`, and `preview` expose active state
      through `data-veritas-newsletter-tab-active`; editor/preview are disabled
      until selection.

### Templates View

- [x] **Template card** —
      `[data-veritas-newsletter-template-card="<template-id>"]` is keyboardable,
      labelled `Use <template name>`, exposes fixture frequency/section count,
      and switches to editor view.

### Editor View

- [x] **Back to templates** —
      `[data-veritas-newsletter-action="back-to-templates"]` switches back to
      the template gallery.
- [x] **Subject / preheader inputs** — `[data-veritas-newsletter-subject-input]`
      and `[data-veritas-newsletter-preheader-input]` edit local email detail
      state.
- [x] **Preview** — `[data-veritas-newsletter-action="preview"]` switches to
      preview with current editor state.
- [x] **Section toggle** —
      `[data-veritas-newsletter-section-toggle="<section-id>"]`
      expands/collapses
      `[data-veritas-newsletter-section-content="<section-id>"]`.
- [x] **Section reorder** —
      `[data-veritas-newsletter-section-move="<section-id>"]` with
      `data-veritas-newsletter-section-move-direction="up|down"` swaps local
      order.
- [x] **Section remove** —
      `[data-veritas-newsletter-section-remove="<section-id>"]` removes the row
      from local section state.
- [x] **Add section** —
      `[data-veritas-newsletter-add-section-type="<section-type>"]` appends an
      empty section of that type.

### Preview View

- [x] **Back to editor** — `[data-veritas-newsletter-action="back-to-editor"]`
      returns to editor and preserves local edits.
- [x] **Stats** —
      `[data-veritas-newsletter-preview-stat="sections|items|estimated-read-time|template|frequency"]`
      exposes preview values from the active draft.
- [x] **Rendered email** — `[data-veritas-newsletter-preview-panel]` and
      `[data-veritas-newsletter-preview-section="<section-id>"]` render the
      current sections/items.
- [x] **Send preview** — `[data-veritas-newsletter-action="send-preview"]`
      exposes pending state and then `[data-veritas-newsletter-sent-badge]`.
- [x] **HTML export** — `[data-veritas-newsletter-export="html"]` has accessible
      name "Copy newsletter HTML export", generates the current draft as
      standalone HTML, writes to `navigator.clipboard.writeText()` when
      available, falls back to a downloaded HTML file, and surfaces
      `data-veritas-newsletter-export-state="html-copied|html-downloaded|failed"`.
- [x] **PDF export** — `[data-veritas-newsletter-export="pdf"]` has accessible
      name "Open browser print dialog for PDF export", sets
      `data-veritas-newsletter-export-state="pdf-print-requested"`, and calls
      `window.print()` so the browser can save/print the rendered preview.

## Data & Contracts

- **Reads**: `SAMPLE_NEWSLETTER_TEMPLATES` from
  `apps/oshun/web/src/lib/veritas/veritas-extended-simulation.ts`.
- **Types**: `NewsletterTemplate`, `NewsletterSection`, and
  `NewsletterSectionType` from `veritas-extended-types.ts`.
- **Writes**: local React state only (`view`, `selectedTemplate`,
  `editSections`, `editSubject`, `editPreheader`, `sending`, `sent`,
  `exportState`).
- **Realtime / external network**: none for the core route; the builder remains
  usable while the browser context is offline.
- **Send behavior**: simulated client timer only; no email job is queued.
- **Export behavior**: local client export only. HTML export builds escaped,
  standalone markup from the selected template/current editor draft and writes
  it to the Clipboard API when available; if clipboard write is unavailable or
  rejected, it downloads `veritas-<template>.html`. PDF export uses
  browser-native print/save-as-PDF by invoking `window.print()` and print CSS
  that isolates the preview panel. No server render job or asset persistence is
  queued.
- **Telemetry**: no route-local telemetry import or event dispatch.
- **Auth/role check**: shell middleware gates `/domains/veritas/*`.
- **Page metadata**: no `Metadata` export in this client page; the screen-reader
  `<h1>` reads "Newsletter Builder · Veritas · OSHUN".

## Current E2E Evidence

- `apps/oshun/web/e2e/veritas-newsletter-builder.spec.ts`
  - Desktop templates: fixture total, disabled tabs before selection, accessible
    44×44 close, reduced-motion card animation, keyboard template selection, and
    keyboard close.
  - Editor: seeded subject/preheader, section expansion with item metadata,
    reorder, remove, add-section, edited details, preview transition, preview
    stats, edited preheader rendering, and return-to-editor state preservation.
  - Preview/send/export: selected-template stats, rendered preview sections,
    sending state, sent badge, copied standalone HTML payload containing the
    template/section/item content, HTML export state, PDF print-request state,
    and the browser print invocation.
  - Standalone/offline mobile: PWA relaunch, offline template selection, section
    expansion, preview, simulated send, reduced motion, and no horizontal
    overflow at 390×844.

## Cross-References

- Component:
  `apps/oshun/web/src/components/domains/veritas/VeritasNewsletterBuilder.tsx`
- Route: `apps/oshun/web/src/app/domains/veritas/newsletter/page.tsx`
- Adjacent reader/editor component:
  `apps/oshun/web/src/components/domains/veritas/VeritasNewsletter.tsx`
- Sibling tools:
  - [`domains-veritas-headlines.md`](./domains-veritas-headlines.md)
  - [`domains-veritas-research.md`](./domains-veritas-research.md)
  - [`domains-veritas-articles.md`](./domains-veritas-articles.md)
- Customer-facing Veritas surfaces: [`veritas.md`](./veritas.md)
- Feature spec: [`V1/features.md`](../../../V1/features.md#veritas)

## Open Questions / Known Gaps

- [ ] Drafts, removed sections, reordered sections, and sent state are
      session-local only; they do not persist through reload or sync to a user
      Library/subscription store.
- [ ] Send Preview is a simulated timer and does not enqueue an email job.
- [ ] No telemetry currently records template selection, editor changes,
      preview, send, or export intent.
- [ ] The reader component `VeritasNewsletter` remains adjacent to this builder;
      confirm whether it is the subscriber-facing counterpart or a legacy
      preview surface.
