···11+# Reading-page author focus — design
22+33+**Date:** 2026-06-09
44+**Status:** Approved
55+66+## Problem
77+88+The reading pages (publication index and single post) lead with SkyPress's own
99+identity — the SkyPress logo + wordmark in the header. For readers, the focus should
1010+be on the *publication* and its *author*, not on the platform.
1111+1212+## Goals
1313+1414+1. Publication page: drop the SkyPress header entirely.
1515+2. Single post page: replace the SkyPress logo/title in the header with the
1616+ **publication** logo + title.
1717+3. Single post page: replace the publication name in the `reader__meta` eyebrow with
1818+ the **author's** name, avatar, and handle.
1919+4. Both pages: render dates in a long, human format (e.g. "June 9, 2026").
2020+2121+## Non-goals
2222+2323+- No client-side JavaScript on the reading pages (they stay server-only — see
2424+ AGENTS.md hard constraint #3).
2525+- No locale negotiation: the UI is English, so dates render in a fixed
2626+ `en-US` long format. ("Controlled by the browser" was considered and dropped in
2727+ favour of a simpler, JS-free fixed format.)
2828+- No changes to the writer profile page, RSS feeds, theming, or OG meta.
2929+3030+## Design
3131+3232+### 1. Shared date helper (new)
3333+3434+`src/lib/reader/dates.ts` exports a pure function:
3535+3636+```ts
3737+export function formatLongDate( iso: string ): string;
3838+```
3939+4040+Implemented with `Intl.DateTimeFormat( 'en-US', { dateStyle: 'long', timeZone: 'UTC' } )`.
4141+4242+- `timeZone: 'UTC'` pins the rendered day: a `2026-06-09T23:00:00Z` timestamp must not
4343+ roll to the 10th (or back to the 8th) depending on the server's local zone. It also
4444+ keeps unit tests deterministic.
4545+- Output example: `formatLongDate( '2026-06-09T12:00:00Z' ) === 'June 9, 2026'`.
4646+- Callers keep their own null-handling (`publishedAt ? formatLongDate( publishedAt ) : null`),
4747+ so the helper only ever receives a real ISO string.
4848+4949+### 2. Publication page — `src/pages/[author]/[slug]/index.astro`
5050+5151+- Remove the `<header class="masthead"><a href="/"><Logo /></a></header>` block.
5252+- Remove the now-unused `Logo` import and the `.masthead` CSS rules.
5353+- Change the article date mapping from `record.value.publishedAt?.slice( 0, 10 )` to
5454+ `record.value.publishedAt ? formatLongDate( record.value.publishedAt ) : null`.
5555+5656+The publication hero (logo, title, byline, lede) already carries publication +
5757+author identity, so no header is needed.
5858+5959+### 3. Single post page — `src/pages/[author]/[slug]/[rkey].astro`
6060+6161+**Data.** Add `fetchActorProfile` (mirroring the publication page) so the author's
6262+`displayName` and `avatar` are available. Compute:
6363+6464+- `authorName = profile.displayName ?? \`@${ handle }\``
6565+- publication `logoUrl` via `buildGetBlobUrl( pdsUrl, did, publication.icon.ref.$link )`
6666+ when `publication.icon` exists, else `null`; `initial = publication.name.charAt(0).toUpperCase()`.
6767+6868+**Header.** Replace `<a href="/"><Logo /></a>` with a link to `pubUrl`
6969+(`/@handle/slug`) containing the publication logo (or initial-letter fallback) and
7070+the publication title.
7171+7272+**Eyebrow (`reader__meta`).** Replace the publication-name link with an author block
7373+linking to `/@handle`:
7474+7575+```
7676+[avatar] Author Name @handle · June 9, 2026 · updated June 10, 2026 · 5 min read
7777+```
7878+7979+- Avatar shown only when `profile.avatar` exists.
8080+- When `displayName` is absent, show just `@handle` once (no duplicated handle).
8181+- Date(s) via `formatLongDate`.
8282+8383+**Cleanup.** Drop the `Logo` import and the `.reader__author` rule (replaced by new
8484+author-block + header styles).
8585+8686+### 4. Tests
8787+8888+- TDD: write `src/lib/reader/dates.test.ts` first — covers the long-format output,
8989+ UTC pinning (a late-evening UTC timestamp stays on its calendar day), and a
9090+ date-only string.
9191+- Inspect existing colocated `_*.test.ts` for these two pages; update any assertions
9292+ that reference the removed masthead or the old `YYYY-MM-DD` date format.
9393+- Gate: `npm run test` and `npm run check` must pass.
9494+9595+## Risks / notes
9696+9797+- Colocated tests under `src/pages/` MUST stay underscore-prefixed (AGENTS.md #8).
9898+- Single post page newly depends on the actor profile fetch; if the profile fetch
9999+ fails it should degrade to `@handle` rather than erroring the page (match the
100100+ publication page's tolerance).