From ed67a0dce01698abacb07fedd5b03d93f1db5fad Mon Sep 17 00:00:00 2001 From: Efthimios Fousekis Date: Tue, 28 Jul 2026 01:07:30 +0300 Subject: [PATCH] feat(frontend): honest generation wait-time copy + humanize em-dashes --- frontend/e2e/journey.spec.ts | 2 +- frontend/index.html | 4 +-- frontend/src/components/ExampleReel.tsx | 2 +- frontend/src/components/Footer.tsx | 2 +- frontend/src/components/HashChip.tsx | 2 +- frontend/src/components/Hero.tsx | 12 +++---- frontend/src/components/HowItWorks.tsx | 4 +-- .../src/components/ProvenancePanel.test.tsx | 2 +- frontend/src/components/ProvenancePanel.tsx | 6 ++-- frontend/src/components/ShareBar.tsx | 8 ++--- .../components/steps/GenerateReel.test.tsx | 24 +++++++++++++- .../src/components/steps/GenerateReel.tsx | 32 ++++++++++++++----- .../src/components/steps/OccasionPicker.tsx | 2 +- frontend/src/components/steps/PhotoUpload.tsx | 4 +-- frontend/src/components/steps/ReelResult.tsx | 2 +- frontend/src/lib/api.ts | 2 +- frontend/src/lib/provenance-verify.ts | 8 ++--- frontend/src/lib/utils.test.ts | 6 ++-- frontend/src/lib/utils.ts | 4 +-- 19 files changed, 83 insertions(+), 45 deletions(-) diff --git a/frontend/e2e/journey.spec.ts b/frontend/e2e/journey.spec.ts index b982142..93516ce 100644 --- a/frontend/e2e/journey.spec.ts +++ b/frontend/e2e/journey.spec.ts @@ -130,7 +130,7 @@ async function walkJourney(page: Page, opts: WalkOpts): Promise { // The server-side aggregate re-verification receipt also renders: a text // summary (never colour alone) plus the individual named checks. - await expect(page.getByText(/checks passed — all verified/i)).toBeVisible(); + await expect(page.getByText(/checks passed\. all verified/i)).toBeVisible(); await expect(page.getByText(/reel bytes match the sealed hash/i)).toBeVisible(); await assertNoHorizontalOverflow(page, `${opts.label} result (verified)`); } diff --git a/frontend/index.html b/frontend/index.html index da2963d..7bb0110 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -7,9 +7,9 @@ - Cinemory — your memories, made into film + Cinemory: your memories, made into film diff --git a/frontend/src/components/ExampleReel.tsx b/frontend/src/components/ExampleReel.tsx index 2799698..6e05403 100644 --- a/frontend/src/components/ExampleReel.tsx +++ b/frontend/src/components/ExampleReel.tsx @@ -45,7 +45,7 @@ export function ExampleReel() { return (
{frames.map((src, i) => ( diff --git a/frontend/src/components/Footer.tsx b/frontend/src/components/Footer.tsx index af5197b..77061f4 100644 --- a/frontend/src/components/Footer.tsx +++ b/frontend/src/components/Footer.tsx @@ -4,7 +4,7 @@ export function Footer() { return (
-

© {new Date().getFullYear()} Cinemory — your memories, made into film.

+

© {new Date().getFullYear()} Cinemory. Your memories, made into film.

{/* The repo link is a standalone control (not buried mid-sentence) so it is a real >=44px tap target on touch, tightening on >=sm. */}
diff --git a/frontend/src/components/HashChip.tsx b/frontend/src/components/HashChip.tsx index bfffb27..c0e4370 100644 --- a/frontend/src/components/HashChip.tsx +++ b/frontend/src/components/HashChip.tsx @@ -30,7 +30,7 @@ export function HashChip({ type="button" onClick={copy} disabled={!hash} - title={hash ? `${label ? label + ": " : ""}${hash} — click to copy` : "unavailable"} + title={hash ? `${label ? label + ": " : ""}${hash} (click to copy)` : "unavailable"} className={cn( "group inline-flex min-h-11 items-center gap-1.5 rounded-md border border-white/[0.08] bg-ink-900/70 px-2 py-1 font-mono text-xs text-zinc-300 transition-colors hover:border-gold-400/40 hover:text-gold-200 disabled:opacity-50 sm:min-h-0", className, diff --git a/frontend/src/components/Hero.tsx b/frontend/src/components/Hero.tsx index 45e6a80..bd5c705 100644 --- a/frontend/src/components/Hero.tsx +++ b/frontend/src/components/Hero.tsx @@ -8,17 +8,17 @@ const features = [ { icon: Film, title: "Cinematic by default", - body: "Music-driven cuts, chapter bridges and title cards — an editor’s eye, automated.", + body: "Music-driven cuts, chapter bridges and title cards: an editor’s eye, automated.", }, { icon: Sparkles, title: "Occasion-aware", - body: "Anniversary, wedding, graduation, year-in-review — each with its own pacing and score.", + body: "Anniversary, wedding, graduation, year-in-review: each with its own pacing and score.", }, { icon: ShieldCheck, title: "Provenance-sealed", - body: "Every asset is SHA-256 hashed and the manifest is sealed — verifiable, tamper-evident.", + body: "Every asset is SHA-256 hashed and the manifest is sealed: verifiable, tamper-evident.", }, ]; @@ -83,7 +83,7 @@ export function Hero({ className="mt-6 max-w-xl text-balance text-lg text-zinc-400" > Cinemory turns a handful of photos into a scored, stitched cinematic - reel — and seals it with cryptographic provenance you can verify. + reel, and seals it with cryptographic provenance you can verify. - Made for families, couples and small teams — no video editor required. + Made for families, couples and small teams. No video editor required. - No account · No watermark · ~30 seconds + No account · No watermark {/* A live, muted, looping example of the generative output. */} diff --git a/frontend/src/components/HowItWorks.tsx b/frontend/src/components/HowItWorks.tsx index f2b687f..6edb437 100644 --- a/frontend/src/components/HowItWorks.tsx +++ b/frontend/src/components/HowItWorks.tsx @@ -5,7 +5,7 @@ const STEPS = [ { icon: ImagePlus, title: "Add your photos", - body: "Drop in a handful of moments — the order you choose becomes the edit.", + body: "Drop in a handful of moments. The order you choose becomes the edit.", }, { icon: Sparkles, @@ -15,7 +15,7 @@ const STEPS = [ { icon: ShieldCheck, title: "Get a sealed reel", - body: "A cinematic reel you can play, share and cryptographically verify — in seconds.", + body: "A cinematic reel you can play, share and cryptographically verify in seconds.", }, ]; diff --git a/frontend/src/components/ProvenancePanel.test.tsx b/frontend/src/components/ProvenancePanel.test.tsx index 3940733..5f9c0f6 100644 --- a/frontend/src/components/ProvenancePanel.test.tsx +++ b/frontend/src/components/ProvenancePanel.test.tsx @@ -141,7 +141,7 @@ describe(" — server-side aggregate re-verification", () => await userEvent.click(screen.getByRole("button", { name: /verify provenance/i })); expect( - await screen.findByText(/2\/2 checks passed — all verified/i), + await screen.findByText(/2\/2 checks passed\. all verified/i), ).toBeInTheDocument(); expect(screen.getByText(/reel bytes match the sealed hash/i)).toBeInTheDocument(); // Non-colour-only: an explicit textual "Passed" label per check. diff --git a/frontend/src/components/ProvenancePanel.tsx b/frontend/src/components/ProvenancePanel.tsx index 47fb8fd..5ebd657 100644 --- a/frontend/src/components/ProvenancePanel.tsx +++ b/frontend/src/components/ProvenancePanel.tsx @@ -74,7 +74,7 @@ export function ProvenancePanel({ reel }: { reel: ReelResponse }) {

Every asset is content-addressed by SHA-256 and the manifest is - sealed — tampering with any field breaks the hash. + sealed. Tampering with any field breaks the hash.

@@ -138,7 +138,7 @@ export function ProvenancePanel({ reel }: { reel: ReelResponse }) {

- {reel.reel_url ?? "—"} + {reel.reel_url ?? "(none)"}

@@ -312,7 +312,7 @@ function ServerRecheck({ receipt }: { receipt: ReceiptUiState }) { } > {passed}/{checks.length} checks passed - {allPassed ? " — all verified" : " — tamper detected"} + {allPassed ? ". All verified." : ". Tamper detected."}