P.1 + P.3 + P.4 + P.7: empty-state polish + pulse substance + /m alias + /next roadmap
+194 / −226 files
Files changed
- Acontent/en/next.md+61 / −0
- Asrc/app/m/[id]/page.tsx+12 / −0
- Msrc/marketing/components/homepage.tsx+2 / −2
- Msrc/marketing/components/named-betrayal-beat.tsx+21 / −12
- Msrc/marketing/components/real-human-beat.tsx+14 / −6
- Msrc/shared/pulse/query.ts+84 / −2
Diff
Lines reveal in sequence as you scroll. First 20 lines per file shown — expand for the rest.
content/en/next.md+61 / −0markdown| @@ -0,0 +1,61 @@ | |
| + | --- |
| + | title: "Next" |
| + | description: "What the operator is working on this week. Public, day-stamped, accountable. Members can react. Indications inform; only Hall proposal votes are binding." |
| + | slug: "next" |
| + | subtitle: "What we're working on this week." |
| + | datePublished: "2026-04-27" |
| + | dateModified: "2026-04-27" |
| + | priority: 0.5 |
| + | changeFrequency: weekly |
| + | ogType: article |
| + | schema: Article |
| + | layout: content |
| + | readingTime: 2 |
| + | navLabel: "Next" |
| + | navOrder: 5 |
| + | --- |
| + | |
| + | *Operator-published, day-stamped. Updated weekly. Members react with the five reaction kinds; the operator publishes a one-line note when reactions shift the plan. Indications are non-binding — only Hall proposal votes are.* |
| + |
src/app/m/[id]/page.tsx+12 / −0tsx| @@ -0,0 +1,12 @@ | |
| + | import { permanentRedirect } from "next/navigation"; |
| + | |
| + | interface Props { |
| + | params: Promise<{ id: string }>; |
| + | } |
| + | |
| + | export const dynamic = "force-dynamic"; |
| + | |
| + | export default async function MemberAliasPage({ params }: Props) { |
| + | const { id } = await params; |
| + | permanentRedirect(`/hall/members/${id}`); |
| + | } |
src/marketing/components/homepage.tsx+2 / −2tsx| @@ -10,7 +10,7 @@ import { | |
| getReservationsOrderedByPosition, | |
| spotsRemaining as getSpotsRemaining, | |
| } from "@/shared/reservations"; | |
| − | import { getLatestPulseEvents } from "@/shared/pulse/query"; |
| + | import { getInitialPulseEvents } from "@/shared/pulse/query"; |
| import type { PulsePayload } from "@/shared/db/schema/pulse-events"; | |
| import { SubscribeForm } from "./subscribe-form"; | |
| import { CountersStrip } from "./counters-strip"; | |
| @@ -89,7 +89,7 @@ export async function Homepage() { | |
| countAiCommitsEver().catch(() => 0), | |
| userId ? existingSignatureForUser(userId).catch(() => null) : Promise.resolve(null), | |
| getReservationsOrderedByPosition(32).catch(() => []), | |
| − | getLatestPulseEvents(8).catch(() => []), |
| + | getInitialPulseEvents(8).catch(() => []), |
| getContentBySlug("constitution", "en").catch(() => null), | |
| ]); | |
src/marketing/components/named-betrayal-beat.tsx+21 / −12tsx| @@ -42,24 +42,33 @@ export async function NamedBetrayalBeat() { | |
| <BeatShell label="Beat 1 · The named betrayal"> | |
| <div className="flex flex-col gap-6 rounded-2xl border-2 border-dashed border-stone-300 bg-stone-50 px-6 py-10 md:px-8 md:py-12"> | |
| <p className="font-sans text-[11px] font-medium uppercase tracking-[0.25em] text-stone-500"> | |
| − | First refusal lands soon |
| + | Refusals being drafted now |
| </p> | |
| <p className="font-serif text-2xl leading-tight tracking-tight text-stone-900 md:text-3xl"> | |
| One Elephant card rotates here every week — the most consequential | |
| − | refusal Our.one has made to one of the apps you use today. |
| + | refusal Our.one has made to one of the apps you already use. |
| </p> | |
| <p className="font-sans text-sm leading-relaxed text-stone-600"> | |
| − | <em>What every other social app does</em> on the left;{" "} |
| − | <em>what Our.one constitutionally refuses</em> on the right; the |
| − | named human who originated the refusal underneath. Each cited from |
| − | the incumbent’s own sources. Each shareable. |
| + | Every refusal is cited from the incumbent’s own engineering |
| + | blog or public statements. Side-by-side: <em>how they do it</em>{" "} |
| + | against <em>how Our.one constitutionally refuses to</em>. Each |
src/marketing/components/real-human-beat.tsx+14 / −6tsx| @@ -119,12 +119,20 @@ export async function RealHumanBeat() { | |
| The card on this surface is a name, a number, and the pool they | |
| earn from. Generic until then is the honest read. | |
| </p> | |
| − | <Link |
| − | href="/manifesto" |
| − | className="mt-6 inline-flex font-sans text-sm font-medium text-stone-900 underline decoration-stone-300 underline-offset-[6px] hover:decoration-stone-900" |
| − | > |
| − | Read why this matters → |
| − | </Link> |
| + | <div className="mt-6 flex flex-wrap items-center gap-5"> |
| + | <Link |
| + | href="/constitution" |
| + | className="font-sans text-sm font-medium text-stone-900 underline decoration-stone-300 underline-offset-[6px] hover:decoration-stone-900" |
| + | > |
| + | Read what the contract says → |
| + | </Link> |
| + | <Link |
| + | href="/manifesto" |
| + | className="font-sans text-sm font-medium text-stone-900 underline decoration-stone-300 underline-offset-[6px] hover:decoration-stone-900" |