Changelog

What's new.

Recent features, improvements, and fixes.

June 6, 2026

featureAdmins can create username/password accounts with no email send

Replaced the email-invite flow for new users with direct username + password provisioning. The reason was operational: every invite went through Supabase's inviteUserByEmail, which is capped at a small number of email sends per day — so onboarding a handful of people at once would silently fail. The new path sidesteps email entirely. In /admin → Users, the old "Send invite" form is now "Create user": enter a name, username, password (with a Generate button), and role, and the account exists immediately. Under the hood it calls adminClient.auth.admin.createUser({ email_confirm: true }), which marks the account confirmed without sending anything. Because Supabase Auth is keyed on email, each username account gets a deterministic synthetic, non-routable email — <username>@users.makeapoint.local — stored in profiles.email; the real identifier is the new profiles.username column (citext, unique). The login screen's first field is now "Username or email" and maps a bare username to its placeholder email before signing in, so existing email users keep working unchanged. Roles are unaffected — still profiles.role, with the same last-admin guards. Per the requirement to view a password later (Supabase only keeps an unrecoverable hash), each password is also stored AES-256-GCM-encrypted in a new, service-role-only user_secrets table, decryptable only with the server-side USER_CRED_ENCRYPTION_KEY; admins get "Show password" and "Reset password" row actions. The tradeoff is explicit: this is a recoverable credential vault, isolated from profiles and reachable only through an admin-gated route. Note that username accounts have no inbox, so the "Forgot password" page can't help them — admin reset is the recovery path. Ships with a manual Supabase migration (supabase/migrations/username_password_accounts.sql) and a new env var.

May 31, 2026

improvementReal "make a point." wordmark replaces the placeholder logo

Swapped the hand-built SVG approximation of the logo (an inline path mockup with the orange "a" circle) for the official brand wordmark Lior supplied. The on-page logo is now the vector file at public/logo.svg (599×96, ≈6.24:1), rendered by components/Logo.tsx via a plain <img> — next/image's optimizer rejects SVGs unless dangerouslyAllowSVG is set, and serving straight from /public sidesteps that while keeping the mark crisp at every size. The component API is unchanged (className for responsive sizing, height for fixed-pixel placements), so all ten call sites kept working without logic changes. To honour the brand's minimum-size guidelines (≥177px wide on desktop, ≥152px on mobile) under the new, wider aspect ratio, three placements that would have rendered below the floor were nudged up: the Nav logo from h-5 to h-7 on mobile (125px → 175px), the homepage hero from h-6 to h-7 on mobile (150px → 175px), and the auth/login pages from height 28 to 30 (175px → 187px). The old placeholder public/logo.png was replaced in place with the new brand PNG rather than deleted, because three structured-data / Open Graph references (the homepage Organization JSON-LD logo plus the /analyze and /deck example pages) point at /logo.png and social crawlers want a raster, not an SVG — so OG and schema.org consumers now get a correct raster of the new mark while on-page rendering uses the vector.

May 28, 2026

feature/admin Prompt tab restructured + new "View full prompt" drawer

Two coordinated changes addressing the same problem — the Prompt tab had grown to seven stacked sections (Mode toggle, About, Blocks, Instructions, Reference Files, A/B Testing, History) at roughly equal visual weight, and Lior had no way to see the full assembled prompt that Claude actually receives (only her editorial slice). (1) New "View full prompt" button next to Audit on the editor card opens a right-side drawer showing the literal concatenation order: SECURITY_PROMPT → editorial draft → RENDERING_PROMPT (assembled with current block labels/order) → reference files → FORMATTING_INSTRUCTION. Each section is labelled with a Locked/Yours/Files chip in grey/green/blue and a one-line description; the editorial section is highlighted with a green border so the "this is the part you control" boundary is visceral. Copy-all button copies the full assembled string. Voice mode hides References + Output hygiene since /speak doesn't use them. New endpoint /api/admin/system-prompt/preview returns the scaffolding pieces (reuses existing buildRenderingPrompt + getBlockConfig + attachments loader from buildAuditPayload's logic; no duplication). New component SystemPromptPreview mirrors PromptAuditPanel's drawer pattern. (2) Prompt tab is now split into three sub-tabs at the top: Write / Experiments / History. Write holds the editorial textarea + Blocks + Reference Files (the daily edit screen); Experiments holds A/B variants; History holds past versions. Persistent sticky header at the top of the tab shows the mode toggle (Text/Voice) on the left and a save-status pill on the right that turns orange on unsaved changes — visible regardless of sub-tab. "Instructions" heading renamed to "Crystal's editorial prompt" so it self-describes. Primary Save button repainted brand orange (#EC6526) — Audit + View full prompt are ghost buttons. Added a small ghost Save at the top-right of the editor card so long-prompt edits don't require scrolling to save. Removed the "About this prompt — what you control vs what's locked" block (~120 lines) entirely — its job (telling Lior what's editable) is now done concretely by View full prompt + the sub-tab structure. Reference Files moved inside Write (no separate sub-tab) since uploads are an occasional Write-flow action, not a destination.

May 25, 2026

fixGuide editor now understands pasted Markdown

Pasting markdown into the admin guide editor used to land literal `**bold**` and `# Heading` characters in body_html (the Tiptap WYSIWYG treats arbitrary plain text as a single paragraph). Added a handlePaste hook on the editor that detects markdown on the clipboard, runs it through `marked` (gfm + breaks), sanitises with DOMPurify, then inserts as a real ProseMirror slice via @tiptap/pm/model's DOMParser. The detection heuristic is conservative on purpose: strong single signals (any heading, code fence, real `[text](url)` link, or two consecutive list items) qualify alone; weaker signals (single bold/italic, single list item, single blockquote) need 2+ to combine — so pasting a normal paragraph that happens to contain an asterisk doesn't get auto-converted. Non-markdown paste falls through to Tiptap's default. Round-trip stays one-way: paste converts to HTML, then the editor and body_html column stay HTML-only (no schema change). Added dompurify + @types/dompurify (marked was already installed). The public guide page at /guides/[slug] is unchanged — it still renders body_html via dangerouslySetInnerHTML, but the HTML it receives is now actually structured instead of a paragraph full of asterisks.

May 22, 2026

featureHomepage gets an interactive composer that warms users into /analyze

Replaced the inert "Write / Paste / Upload / Record" widget on the homepage (which has been a static teaser since the 2026-05-15 entry-point disable) with a working three-field composer based on Lior's HTML mockup. Audience + Setting + message are required to enable Get feedback; Setting is a combobox with 5 preset categories (Leadership forums, Team updates, Sales conversations, Investor pitch, Conferences & events) plus a free-text "Use: …" escape hatch that captures whatever the user types. Submit is a LURE, not a real backend call — we stash audience/setting/cta into the same localStorage keys /analyze's ContextFields.tsx reads (analyze_audience / analyze_event_type / analyze_goal) plus the typed message into sessionStorage.makeapoint_prefill (the key /analyze already hydrates from for /history "Try again"), then router.push("/analyze"). The /analyze page picks up everything on first mount — user is one click from running the analysis with their typed content carried across. Upload + Record mode tabs are teasers: clicking them carries context forward and routes to /analyze where the real /api/upload pipeline and mic recorder live. Same component also replaces the homepage's "benefits" 3-card row and the closing "Fix it before it matters" section — Lior's How it works (numbered cards with body copy) and closing CTA (with a Try it › button that scrolls back to the audience field) read richer. The essays/"Do it right" section is untouched. Schema decision: Setting (combobox, homepage) maps to the existing /analyze "Opportunity or occasion" free-text field at the storage boundary; the two labels diverge on purpose for now while we see how the new framing reads. If Lior likes it we'll align /analyze's label in a follow-up. Styling kept as a scoped <style> block under .mp inside the component, matching the existing homepage convention (also a single inline <style> block). Removed ~80 lines of now-unused .hp CSS for .try-panel, .benefits, .closing, and their mobile breakpoints.

feature/analyze now accepts .pptx uploads

Drop a .pptx into the /analyze "Write it" textarea and Ms. Crystal (Clear) reads it. The /deck feature already shipped a battle-tested PPTX parser (lib/deck/parsePptx.ts — JSZip + fast-xml-parser, extracts slide title + body + speaker notes from every slide, walks grouped shapes recursively, ignores charts/SmartArt/embedded objects). We hooked it into lib/extractText.ts behind the same /api/upload entry point that already handles PDF/DOCX/TXT, so the rest of the flow — textarea population, edit-before-submit, 20K-char transcript ceiling, daily quota — is unchanged. The flattening step renders each slide as `[Slide N — Title] body Notes: …` joined with blank lines, giving the model enough structure to say things like "slide 3 buries the lede" while still reading as plain text. UI copy updated in 6 places (WriteMode placeholder + tooltip + accept attr + error copy + header comment, plus the ModeTabs Write-it tooltip). One bonus: the existing "this looks like a slide-deck PDF" error now points users to upload the original .pptx instead of pasting. Note: the 4MB upload cap stays — it's pegged to Vercel's 4.5MB serverless body limit, not a config knob. Users with big media-heavy decks still get routed to /deck (which uses direct-to-Supabase-Storage upload and is the better product for slide-by-slide rewrite anyway). Zero new dependencies; no prompt changes; the PPTX flow reuses the same system prompt as typed/pasted text.

May 18, 2026

fixForgot-password flow + admin resend now works for confirmed users

Two coordinated auth fixes after Lior couldn't get back into his account. (1) New public /auth/forgot-password page — enter your email, get a reset link, click through to /auth/set-password (the existing post-invite page already calls supabase.auth.updateUser, which works equally well for recovery sessions). Linked from /login as a small "Forgot password?" affordance next to the password label. Uses supabase.auth.resetPasswordForEmail and the existing /auth/callback handler (which already accepts type=recovery via its OTP branch). (2) Fixed the admin "Resend invite" button: it was calling adminClient.auth.admin.inviteUserByEmail unconditionally, which errors with "User already registered" once a user has confirmed their email — so for any returning user who'd forgotten their password, the admin saw success-ish UI but the email never sent. Now the API route checks targetUser.email_confirmed_at and either re-invites (unconfirmed) or sends a password-recovery email (confirmed). Admin toast updates to "Password reset email sent to X" vs "Invite resent to X" so the admin can tell which one went out. No DB schema changes; no Supabase dashboard changes required (the default "Reset Password" email template ships enabled).

May 15, 2026

featureNew modular composer is now the default /analyze

Promoted the /analyze-v2 modular composer to /analyze and closed every gap that would have caused a regression. The new UI: 3 context fields (Audience, Opportunity, Call to action) above a composer card whose body morphs by tab — Write it (textarea + paste + drag-drop file upload), Say it (mic recording + 3-tries loop, no longer a separate /speak detour), and visible Show it / Slides teasers. Submission writes to the same sessionStorage keys as before so /results works unchanged. Behaviour ported from the old /analyze so nothing breaks: daily-quota check (warns at 40/day, blocks at 50), ?error=daily_limit_reached and ?error=prompt_not_configured handling for /results redirects, ?welcome=1 override, makeapoint_prefill read for /history 'Try again', makeapoint_analyze_draft auto-save so a tab close doesn't drop typed work, first-time welcome card with sample loader and 5-section preview pills (Scorecard › So What › Word-by-word › Your dictionary › Rewrite), 'or try a sample' link for returning users with empty content, pass-count footer, 'Ms. Crystal (Clear) is reading…' pending copy, privacy and storage disclaimers, brand intro headline. Fixed a regression in the v2 char counter — it was showing /5,000 but the real limit is 20,000 (now /20,000). components/analyze-v2/ renamed to components/analyze/, app/analyze-v2/ deleted. /speak still works standalone but is no longer linked from /analyze since the Say it tab covers the same flow. All site-wide /analyze links (homepage, /history, /login, /not-found, proxy.ts redirect, /results error redirects, /preview/*) keep working untouched because the route name didn't change — only its contents did.

improvementYour dictionary block + dark So What callout

Two coordinated visual changes to the /analyze feedback output. (1) The 'Stop Using' block — a single red card listing words to cut — is now 'Your dictionary', a two-pane card with 'Use' (green, words from the run worth keeping) and 'Don't use' (red, words to cut). Pulls both lists from the green-pill and red-pill words in the word-by-word table above. Same block id under the hood, so saved BlockConfig rows still resolve. Old sessions in /history still render via legacy .fb-stop* CSS that we kept dormant. (2) The 'So What' callout flipped from a light-red background to a near-black (#1A1A1A) one with orange-accent border, white headline, and light-gray bulleted body. Red read as 'danger'; black reads as 'this is the most important block', which matches the prompt's framing. Touched 6 files: globals.css (new .fb-dictionary styles + dark .fb-callout), renderingPrompt.ts (new block template), manifest.ts (label rename), validator.ts (new 2-pane spec), BlockPreview.tsx (admin preview), exampleFixture.ts (marketing showcase). Lior's editable prompt textarea needs a paired update: replace the 'Stop Using:' instruction with a 'Your dictionary:' instruction that names both sub-lists — paste-helper written to _prompt-update-dictionary-2026-05-15.md.

improvementHomepage widget + guide CTAs no longer link to /analyze/example

Removed user-facing entry points to the /analyze/example showcase while the first-touch experience is being redesigned. The /analyze/example route, fixture, OG image, and sitemap entry all stay in the backend untouched. Specifically: (1) the homepage 'Write…' textarea and 'Get feedback' button (previously navigation links) are now plain divs with aria-disabled and the misleading hover/cursor styles removed — the widget reads as visually present but inert. (2) The 'Pitch critique' card on every /guides/[slug] page (which linked to /analyze/example) was removed, leaving a single centered 'Deck review' card so the section doesn't sit awkwardly in an empty 2-col grid. SEO surfaces (sitemap, robots.txt allow rule) intentionally untouched — Google can still crawl the page from organic search if it ranks; we just removed the internal links.

improvementHard-Earned section renamed to Do it right

Renamed the essays section from "Hard-Earned" to "Do it right" across every user-visible surface: homepage essays eyebrow + section anchor (now #do-it-right), the /guides page title + H1 + OpenGraph metadata, the /guides/[slug] back-link, the breadcrumbs on /deck and /deck/[id] and /deck/example, both nav variants (signed-in and signed-out), the footer Read column, the admin sidebar tab + the active-tab description, and the admin Guides tab heading. 11 source files touched. Past changelog entries that mention "Hard-Earned" are deliberately untouched — they describe what was true at the time. Anyone who linked externally to /#hard-earned will now scroll to top instead of the section (no internal references break).

May 13, 2026

improvementMobile: fix iOS form zoom + stack word-by-word table on phones

Three low-risk mobile-responsiveness fixes from the user-facing audit. (1) The biggest mobile blocker: bumped .textarea-field and .input-field from 15px → 16px so iOS Safari stops auto-zooming when the user taps the /analyze transcript box, the /login password field, or any other input using these classes. The 1px jump is invisible to users but eliminates the page-jump-and-pinch-zoom-back dance that's been hitting every iOS visitor. (2) The word-by-word feedback table now stacks each row top-to-bottom on phones (<640px) instead of cramming the pill and the 10-word comment into two columns that wrap awkwardly. Header row hidden on mobile since each cell is self-labeling at that width. (3) Cleanup: /analyze's 'what you'll get' preview at the top of the page still listed Verdict as one of the blocks. Removed it and corrected the count from 6 → 5 sections (the Verdict block was removed from production on 2026-05-12 but this preview copy hadn't been updated).

improvementAdmin visual system: 27 grays → 7, 12+ font sizes → 7

Surveyed the admin codebase and found ad-hoc visual values had drifted into a soup: 27 distinct gray colours (#FAFAFA, #FAFAF8, #FAFAF7, #F7F7F5, #F5F5F5, #F5F5F2, #F0F0F0, #F0F0EC, #EEEEEE, etc.) used interchangeably as card backgrounds and borders, and 12+ distinct font sizes (8.5, 10, 10.5, 11, 11.5, 12, 12.5, 13, 13.5, 14, etc.) used as nominal 'body text' that all looked close-but-not-equal. Snapped both to small semantic systems: 7 grays (white, card-bg, hairline-border, strong-border, muted-text, body-text, h1-text) and 7 chrome font sizes (11 micro, 13 body, 15 emphasized body, 17 sub-header, 20 section H2, 24 stat numbers, 32 page H1). Two intentional outliers preserved (8px and 9px in BlockPreview for the miniaturized block visualizations). Applied via sed sweeps across 13 admin files with two contextual exceptions (#F0F0EC borders → border-gray, backgrounds → card-gray). 594 line diffs, no functional changes. Effort follow-up to the UX audit that surfaced 22 admin polish items earlier in the week.

improvementAdmin Prompt tab cleanup + audit panel polish

Audit pass on the admin Prompt tab, which had grown messy across the last week of changes. (1) The Prompt tab's daily action — Lior's textarea — is now the first thing visible: About this prompt and Blocks are collapsed by default with Show/Expand affordances, so Lior lands directly on the editor instead of scrolling past reference material. (2) About panel copy refreshed to reflect current reality: six evaluation standards (with investor caveat for Direct Speak), no stale verdict references, the misleading 'HTML doesn't belong' line replaced with an accurate framing that output-format rules are silently overridden by scaffolding. (3) PromptBlocksEditor promoted out of About into its own dedicated section — it's configuration, not info. (4) A/B Testing demoted to a default-closed collapsible with lighter visual weight (white bg + 1px border instead of the heavy gray fill) since it's rare admin work that was competing visually with the daily Instructions card. (5) Audit panel got a width-toggle button (default 720px, expanded ~90vw with a 1100px cap) and bumped its body fonts up for readability — slim mode keeps the prompt editor visible under it, expanded mode is for reading-mode sessions. Preference persists in localStorage. (6) Help (ⓘ) button moved tight to the Audit button so it visually belongs to the action it explains. (7) Active-tab indicator added below the Admin Panel h1 (bold tab name + 1-line description) so deep-scrolled views still show your location. (8) Fixed the long-standing scroll-to-top bug on the Feedback panel: sending a reply was triggering loadFeedback which flipped loading=true and unmounted the entire list. Removed the redundant duplicate 'Last updated' timestamp under the Save buttons; the pill in the section header is now the single source.

improvementSo What block now renders as bullets + prompt/code alignment

Two coordinated fixes. (1) The So What callout on /analyze responses now renders as a one-line headline plus 2–3 short bullet questions instead of a single bolded prose paragraph — matches what Lior had asked for in her editorial prompt for weeks, which the hardcoded template was silently overriding. Coordinated edit across the rendering template (lib/renderingPrompt.ts), the output validator (lib/promptBlocks/validator.ts now expects headline + ≥2 <li> bullets), the CSS (.fb-callout__headline added, .fb-callout__body styled as <ul> with disc bullets, the vestigial strong-rule dropped), and the marketing example fixture. (2) Resolved a long-standing contradiction in the assembled system prompt: the rendering scaffolding mandates HTML divs with fb-* classes, but FORMATTING_INSTRUCTION used to say 'always respond using clean markdown only, no HTML tags'. The model was picking the more concrete HTML templates and ignoring the markdown directive — which made Lior's blockquote specs for Stop Using and Rewrite silently dead. Trimmed FORMATTING_INSTRUCTION down to non-contradictory output hygiene (no HTML entities, no <style> tags, no code-block wrapping). Lior's prompt textarea also gets a paste-ready clean-up of dead cross-references (the 8-block claim, the Block 8 reference, the Five-vs-Six standards heading, the markdown blockquote specs that weren't being followed) — those textarea edits ship separately when Lior saves them in admin.

May 12, 2026

improvementVertical admin sidebar + one-click audit from ratings

Two coordinated admin UX upgrades. (1) The horizontal tab strip becomes a vertical collapsible sidebar (240px expanded / 64px collapsed, preference persisted in localStorage). The orange/blue/gray color groups shipped on 2026-05-11 now read as proper sections — Content / Signal / Operations — each with its own heading and a 3px left accent on the active tab. Emoji icons per tab so a collapsed sidebar still communicates which tab does what. Tabs and content shift in lockstep with a 200ms transition; unread badges (Feedback, Talk to me) ride the icon as corner pills when collapsed. (2) Each row in the Ratings tab gets a 🔍 Audit button that jumps straight to the Prompt tab with the audit drawer open and that session pre-selected — eliminating the manual 'note the session, switch tab, find it again' loop Lior was doing. Button shows only on responseType='initial' rows (audit replays the initial /analyze response, not follow-ups); thumbs-down rows get a filled-orange treatment so failing runs visibly invite action. The audit panel auto-bumps its recent-sessions fetch from 20 → 50 entries when a cross-tab jump targets a session, so older runs are likelier to appear in the picker. Ratings table also redesigned with table-layout: fixed widths — Rating + Audit moved to the leftmost columns for natural scan-then-click, Session and Comment now wrap properly instead of truncating, Date pushed to the right edge.

improvementVerdict section removed from /analyze

The opening Verdict block on /analyze responses is gone. Lior flagged it as noisy and inaccurate — a long, comma-stuffed line listing generic problems instead of naming the sharpest issue, often duplicating what the So What callout said better. New responses now open straight with the Scorecard (renumbered to block 1), then So What, then Word-by-word, then the closing pair. Three files touched: verdict dropped from TEXT_MANIFEST, the verdict fragment + slot removed from renderingPrompt.ts with all sections renumbered and cross-references cleaned (the so_what_callout no longer says "the verdict already said that"; the global rules now explicitly forbid opening with a headline or summary sentence), and the verdict spec removed from TEXT_SPECS so the validator stops asking for a block we no longer want. Voice mode untouched. .fb-verdict CSS, the /analyze/example marketing fixture, and the PDF-export verdict transform are dormant but unchanged — old sessions still render their verdicts normally in history.

featureGrounded prompt audit in admin

Lior can now audit the /analyze system prompt against a real past run instead of guessing where bad responses come from. New "Audit prompt" button in Admin → Prompt opens a side drawer with: a picker of the last 20 runs (👍/👎 chips so failing runs surface first), an optional "What felt wrong?" textarea (pre-filled from any user comment on the run), and a Run audit action. The audit ships the current editor draft + all hidden scaffolding (security/rendering/attachments/formatting) + the run's input/output/rating/complaint to Claude Opus 4.7, which returns up to 5 structured findings. Each finding has four labeled sections written in plain English (no prompt-engineering jargon, banned-words list enforced via system prompt) — What's wrong / Why it matters / Where to fix it / What to do — plus an exact quote of the problematic snippet, optional evidence from the response, and an optional before/after rewrite. The "Where to fix it" chip routes by content-vs-structure heuristic: 📝 In the prompt (Lior can edit + Jump-to-line), 📎 In an attached file (re-upload from Reference Files), or 🔒 In code — needs a developer. Backend: new prompt_audits table with 1-hour cache by (prompt_hash, session_id, complaint_hash), 20/admin/UTC-day rate limit, Anthropic prompt caching on the auditor instructions + scaffolding. Hand-rolled JSON validator drops findings citing out-of-range line numbers. A round "?" help popover next to the button explains the feature in plain English for non-technical use.

May 11, 2026

featureHard-Earned guides now support video

Two new toolbar buttons in the admin guides editor: 🎬 Video uploads an mp4/mov/webm up to 50 MB straight to a new guides-videos Supabase Storage bucket via a signed URL (bypassing Vercel's 4.5 MB body cap), and ▶ YouTube embeds a YouTube URL as a privacy-friendly youtube-nocookie.com iframe. Both render inline in the editor and in published guides. CSP updated for media-src + frame-src. SEO: every published guide containing video emits VideoObject JSON-LD (one per video) wired to the Article schema, an OpenGraph video tag for single-video guides, and Google's video sitemap extension entries so Google can discover them in /sitemap.xml. YouTube thumbnails come from i.ytimg.com automatically; mp4 thumbnails fall back to the guide's featured image (no auto frame extraction).

featureEditable roadmap tab in /admin

Admin → Roadmap is now a real internal tracker, not the static config/roadmap.ts read-only view. New roadmap_items table replaces config as the source of truth for the admin tab (the public /coming-soon page stays config-driven, manually curated by Jonathan). Each row supports: ✓ ship checkbox, category dropdown (Product / Technical / UX / Admin / New module — Legal merged in, 'New module' added so we can flag major product surfaces vs sub-features), priority (high/medium/low), effort, impact, all inline. Click a row to expand and edit title, description, and internal notes. Up/down arrows reorder. Archive button (soft delete with optional reason) or permanent delete. Switch between active and archived views. Phase concept dropped — done checkbox is the single ship/not-ship flag. Migration + idempotent seed script populate the table from the legacy config (57 items).

May 10, 2026

improvementLior's deck-review tweaks across all four agents

Lior's playbook updates routed to the right agents. Slide Critic now flags: periods / full sentences in slide bodies, removable prepositions, titles longer than one line, agendas with >4 items, bullet-list slides (with non-bullet alternatives suggested), missing reason-to-listen on the cover slide, and asks every title rewrite to take the form of a Promo Question. Deck Strategist must include both a Key Takeaways slide and a Call to Action slide (can be merged) and ensure agenda ↔ takeaways mirror each other (Qs answered as As). Slide Content Generator inherits the same rules when rebuilding tiles, plus rewrites agendas as questions with ≥50% you/your. Homework Synthesizer now produces 5 items: 3 deck-specific + 2 universal hygiene checks (font ≥18pt, no stock images) since those can't be detected from parsed text. Verifier gates the new structural rules. /deck upload form gets a new Opportunity field (Meeting/Webinar/Conference) and audience placeholder hints to include roles + companies.

May 9, 2026

improvementUnpublish button on Hard-Earned guides

Admin → Guides → editor: when a guide is published, the left button now reads "Unpublish" (red) and confirms before pulling the guide offline (status → draft, accessible via preview link only). On a draft guide it still reads "Save draft" (neutral) and acts normally — same handler, label and confirmation switch on guide.status. Closes a UX wart where the button silently changed status from published to draft without warning.

improvementCustom OG images, structured data, internal linking

Closing the SEO follow-up list. (1) /analyze/example and /deck/example each get a custom OpenGraph image now (next/og dynamic PNGs) — social shares show page-specific verdict + framework instead of the generic homepage card. (2) JSON-LD Article schema added to both example pages — eligible for Google rich-result treatment. (3) Per-guide bottom CTA expanded from a single small link into a two-card row ("Pitch critique" + "Deck review") so every Hard-Earned essay now seeds two internal links to the showcase pages. Homepage h1 keyword fix held back for a UX call.

featureCrystal explains the arc — narrative framework + role chips

The proposed deck arc was the most important Strategist output in v1.1, but the UI was flat: a row of equal-weight tiles with no visible flow and no explanation of WHY Crystal arranged them this way. v1.2 fixes both. Strategist now emits arc_framework (one-liner naming the pattern, e.g. 'Hook → Problem → Solution → Why now → Proof → Differentiator → Ask') and arc_logic (2–3 sentences on why that shape fits THIS deck for THIS audience). Each tile also gets a narrative_role tag (Hook/Problem/Solution/Differentiator/Why-now/Proof/Ask/Close) rendered as a colored chip. Wide chevron arrows now visibly connect tiles (→ desktop, ↓ mobile). New ArcFrameworkBanner component above the storyline shows the framework + an expandable Crystal logic panel. Migration adds arc_framework + arc_logic columns; narrative_role lives inside the existing proposed_arc JSONB. Pivotmark example fixture updated with believable framework data. Bonus: GET /api/deck/[id] now selects all v1.1 + v1.2 columns explicitly — fixes a latent v1.1 bug where clarifying_questions + storyline_approved + extra_context_revision were dropped on the wire.

improvementSEO-targeted titles + canonical URLs on example pages

Replaced generic "See an example — MakeAPoint" titles on /analyze/example and /deck/example with keyword-targeted ones ("AI feedback on a pitch — example critique by Ms. Crystal | MakeAPoint" and "AI pitch deck review — slide-by-slide critique by Ms. Crystal | MakeAPoint"). Added explicit canonical URLs, OpenGraph url fields, and Twitter card metadata on both pages. Added metadataBase to the root layout so relative URLs across all pages resolve to absolute correctly and the Next.js metadata warning is silenced.

improvementLet Google index the example pages

Both /analyze/example and /deck/example were noindexed and the former was also blocked by robots.txt's broad Disallow: /analyze (prefix matching catches the example too). Removed the noindex meta on both, added an Allow: /analyze/example exception in robots.txt, and listed both in sitemap.xml at priority 0.8 (same as /guides). These pages contain ~1500 words of original Crystal critique content and are the highest-leverage SEO surface after the homepage.

fixLogged-out visitors get a way back home

Nav previously returned null for logged-out users — meaning visitors landing on /guides, /coming-soon, /whats-new, /analyze/example, or /deck/example had no header at all and no way back to /. Nav now renders a minimal public variant (logo + Sign in + Try it free) for unauthed users on every page except / (custom inline nav), /preview (internal), /login, and /auth/* (where it would be redundant). Replaces the standalone PublicShowcaseHeader component, which is removed. Plus: homepage logo now resizes responsively (h-6 on mobile, h-10 on sm+) — previously fixed at 40px which crowded the 60px mobile nav band.

featureHard-Earned essays + site-wide footer

Two surfaces previously missing internal links from /. (1) New Hard-Earned section on the homepage between the benefits grid and the closing CTA — pulls the two most recent published guides server-side and shows them as cards with title, excerpt, and a Read → link. Cross-linking from the highest-authority page = compounding SEO. Section auto-hides if there are no published guides yet. (2) Site-wide footer in app/layout.tsx — three columns (Read / Account / About) covering Hard-Earned, Coming soon, What's new, sign-in, contact, terms, privacy. Fills the gap that previously left /coming-soon and /whats-new only reachable by URL or sitemap.

improvementFaster images, tighter admin gate

Migrated key <img> tags to next/image — Crystal avatars on /results, /speak, /analyze/example, VoiceRecorder; brand Logo; guide featured images on /guides and /guides/[slug]. Adds automatic responsive sizing, lazy-loading, and LCP optimization. Allowed Supabase Storage host in next.config images.remotePatterns. Separately, /admin is now server-side gated: previously it was 'use client' and the role check happened in a useEffect, which briefly exposed the page chrome to non-admins (no data leaked, every API endpoint enforces role server-side, but the tab structure flashed). Page is now a tiny server component that checks role before sending HTML and redirects non-admins to /. AdminClient holds all the original interactive logic, defense-in-depth role check kept inside.

improvementStop losing user work on refresh

/analyze now auto-saves your transcript to localStorage on every keystroke (cleared on submit), so a browser crash or accidental refresh no longer drops what you typed. /deck/[id] step 2 (clarifying answers, edited storyline tiles, free-text revision, keep-original toggles) auto-saves to localStorage keyed per deck and restores on reload — plus a beforeunload warning if you close the tab with unsaved edits. Drafts only restore for decks not yet submitted, so a stale draft can't shadow a real decision. /whats-new and /coming-soon also opened to logged-out visitors (same family as the /guides public-routes fix).

fixQA pass: open Hard-Earned to public, plug a config leak, fix CTA traps

Phase 1 audit fallout. (1) /guides + /guides/[slug] now load for logged-out visitors — they were unintentionally walled by middleware, killing organic traffic to the Hard-Earned essays. (2) Removed /api/debug-prompt, an old debugging endpoint that leaked system-prompt fragments + Supabase URL to any logged-in user. (3) Homepage textarea and guide CTAs now route to /analyze/example instead of /analyze, so logged-out users see the showcase before hitting the login wall (matches the orange Get-feedback button fix). (4) Added <h1>s to /analyze/example and /login for screen-reader navigation and document outline.

featureSee an example before signing up

Homepage "Get feedback" CTA now lands on /analyze/example — a public, server-rendered showcase of a full Ms. Crystal critique (verdict, scorecard, So-What callout, word-by-word table, stop-using list, suggested rewrite). Renders the same components as /results, so what visitors see in the example is exactly what they'll get on their own pitch. Zero token cost, no agent calls. "Try it on your own" CTA at the bottom routes to /analyze for users who want to commit. Sister page to /deck/example.

May 8, 2026

featureGuides: long-form SEO content at /guides

New /guides section with public index + per-guide pages, and a Guides tab in /admin for writing them. Rich-text editor (TipTap) with bold, headings, lists, links, blockquotes, code, horizontal rules, and inline image upload to a public Supabase Storage bucket. Featured image, excerpt, slug auto-generated from title (editable), Save draft / Publish workflow, and a Preview link that lets you check drafts at /guides/[slug]?preview={id} before going live. Public pages render with Tailwind Typography plus brand-color overrides; per-guide SEO metadata + OpenGraph image; sitemap auto-includes published guides. Drafts return 404 to the public.

featureEditable prompt blocks in /admin

Lior can now rename every feedback block and (in text mode) swap stop_using ↔ rewrite directly from the Prompt tab — no engineering ping needed. New rendering-prompt builder assembles the system prompt from a block manifest + DB-saved label/order config; the CSS class contract stays locked. Each block shows a tiny color-correct preview swatch so the block being renamed is visually obvious. New Test button runs the draft prompt through Claude with a canned-but-editable sample, then validates the rendered HTML against a structural manifest (required classes, required children, valid tone modifiers, no rogue <style>/<script>, blocks-in-saved-order). Result is a per-block pass/fail checklist with the raw HTML available on demand. Default config produces byte-identical output to production — invariant covered by sanity tests.

featureReview your transcript on /speak

After Ms. Crystal finishes, a What you said accordion appears above the feedback. It stays closed by default so the feedback is still the hero, and one click reveals the full transcript Deepgram heard. Every word/phrase Ms. Crystal flagged in the word-by-word table is highlighted inline in the same red/yellow/green pill, so you can see exactly where the buzzwords landed in your own speech. Voice sessions now also save the transcript, so you can come back to it later from /history.

featureCopy + Download PDF on /results

Copy now writes both rich HTML and plain text to your clipboard — paste into Google Docs, Notion, or Gmail and the verdict box, scorecard, tables, and color-coded pills come through with formatting intact. New Download PDF button generates a branded report (logo + Ms. Crystal avatar + date + your context + the full feedback) ready to email or archive. Page-numbered footer.

May 7, 2026

improvementSEO + sharing foundations

Per-page metadata so each route gets its own title and snippet in Google. Dynamic OpenGraph image so links shared on Slack, Twitter, and LinkedIn render with a real preview instead of a blank card. robots.txt + sitemap.xml so crawlers index the right pages and skip the auth-gated ones. JSON-LD on the homepage so Google understands what MakeAPoint is. Crystal portrait now uses Next.js Image for automatic responsive sizing and faster loads.

improvementFirst-time welcome + What's next nudge

New users on /analyze now get a richer welcome card that previews the 6 sections of feedback they're about to receive (the same orange pill flow used in admin). After analysis on /results, a What's next? card surfaces /speak and My Projects so the voice mode stops being hidden in the nav. Card has a Don't show again link.

May 6, 2026

improvementNew Help tab in admin

First tab in /admin is now a Help page — orientation card explaining the editorial-vs-locked split, six "How do I…" cards that link to the right tab (tune Ms. Crystal, A/B test, ratings, replies, sessions), and a callout listing when to ping Jonathan. Lands on the same surface anyone opens admin to.

improvementAdmin Prompt tab now explains what you control vs what's locked

A small "About this prompt" panel at the top of the Prompt tab spells out: tone and persona are yours, output structure and HTML are handled by the page. Different content per Text and Voice mode, since they have different fixed structures.

improvementVoice feedback now uses the same green/red visual language

Ms. Crystal (Clear)'s voice analysis now lands in the same look as text feedback — a verdict box at the top, green pills for keywords to keep, color-coded So What status (Landed / Partial / Missing), and a Filler-word watch callout where every filler is highlighted in red. Same five sections, much easier to scan.

featureVoice takes show up in My Projects

Every voice take you record on /speak is now saved to My Projects with the context (audience, occasion, CTA), the date, and the feedback Ms. Crystal (Clear) gave you. Each retry is its own row so you can compare takes. Your transcript is still never saved — you don't read what you said.

improvementVoice prompt editable in admin

The admin Prompt tab now has a Text mode / Voice mode toggle. Voice mode shows the same editor + version history as text, scoped to the /speak prompt — so the voice character can be tuned without touching the database. Reference files and A/B variants stay text-only for now.

featureSay it out loud — voice practice

New /speak page lets you record up to 5 minutes of your pitch and Ms. Crystal (Clear) listens. She returns the strongest keywords from what you actually said, the takeaways that landed, the So Whats (or the missing ones), and a Filler-word watch — "um," "like," "you know" — pinned to where they cost you. The transcript itself stays server-side; you never have to read what you said. Up to 3 takes per session.

featureTalk to me — public contact form

New /contact page with a four-field form (name, email, topic, message) where anyone can reach out without needing an email client. Submissions land in the admin tab "Talk to me" with unread badges, mark-as-read / mark-as-responded actions, and a quick mailto reply link. Honeypot + per-IP rate limit handle basic spam.

improvementTighter, more polished feedback output

Feedback now renders with the full design system applied — hero verdict pull-quote, color-coded scorecard cells, alternating rows in the word-by-word table, and proper Stop Using / Rewrite blocks. Sections lead with greens before reds. Truncated outputs are fixed with a 2x token budget.

improvementRefreshed results page

The results page is now on the same design system as the rest of the app — brand orange buttons (was dark gray), tokenized colors, primitive components, and the new mobile-friendly sticky bottom bar. All feedback rendering, follow-up flow, ratings, and admin A/B tabs work the same.

improvementRebuilt homepage

The landing page now leads with a tighter hero + side quote card, a scrolling ticker of Ms. Crystal one-liners, three principles, a real sample feedback panel showing what the product actually returns, a four-step how-it-works, the creator section, a dark closing CTA, and a real footer. All built on the design system primitives.

May 5, 2026

improvementRefreshed look across the app

Every page is now on the new design system — brand orange CTAs, underlined form fields, tighter typography rhythm, and consistent component primitives. /analyze, /history, /login, /coming-soon, the legal pages, and the nav all got the same treatment.

improvementCleaner feedback indicator

The Feedback tab badge in admin now only lights up when there are unread mentions — not whenever any pending feedback exists. Pending status is still visible inside the tab; the indicator is now signal, not noise.

improvementAccount menu in the nav

A new avatar with your initials sits in the top-right of the nav. Click it to see your name, email, role, and sign out. The same identity block now anchors the top of the mobile menu.

improvementSharper landing page

The home page leads with a concrete claim — sharpen your message in 30 seconds — and explains what the tool does and who it's for. The CTA is now the brand orange, and Lior's bio reads in first person.

featureChat threads on feedback items

Each feedback item in the admin tab now has a conversation thread. Tag teammates to bring them into the discussion — they'll see an unread badge in the nav and a New pill on the feedback card. Threads with unread mentions sort to the top of the list.

fixMagic-link sign-in works again

Fixed the auth callback so it handles both Supabase redirect formats — invite emails now route correctly to the password-setup screen instead of bouncing users to a blank login form.

featureUser management actions

The admin Users tab now supports per-user actions: change role, suspend, reactivate, resend invite, and delete. Last-admin and self-action guards prevent lockout.

improvementRefreshed typography

Body keeps the system font stack (clean, modern, fast). Poppins is loaded for design moments — page titles use Poppins 300 in orange, buttons use Poppins 700. Body color updated to true black.

improvementNew Button component and refreshed brand orange

Introduced a Button component matching the Figma spec (orange/gray/teal variants, four sizes) and updated the brand orange to #EC6526 site-wide.

featureDownload my data

Added a Download my data link on the My Projects page footer, next to Delete my account. Sends a prefilled support email so we can export your transcripts, feedback, and account metadata on request.

improvementTerms and Privacy pages

Added placeholder Terms of Service and Privacy Policy pages so the footer links go somewhere useful. Full versions are coming before public launch.

improvementRoadmap consolidated to admin

Retired the public /roadmap page. The roadmap now lives only in the admin tab, with click-to-expand rows that show notes, original messages, admin notes, and full metadata.

improvementWhat's New moved to the nav

The changelog now lives at /whats-new, reachable from a bell icon in the top nav. A small orange dot signals when there's something new to read.

improvementNew Logo

Refreshed the makeapoint.ai logo across the landing page header and the in-app navigation.

May 5, 2025

improvementNew Favicon

Updated the browser tab icon to match the MakeAPoint logo: the orange 'a' circle.

featureA/B Testing for Prompts

Test alternative prompts side-by-side. Enable Variant B or C in the Prompt tab, then run an analysis to see comparison tabs on the results page. Admin-only feature for evaluating prompt performance.

May 4, 2025

featurePrompt History

Store and restore the last 5 system prompt versions. Add optional notes when saving. Access via the Prompt tab.

improvementResults Typography

Improved readability with editorial spacing: larger body text (16px), better line height (1.8), clearer heading hierarchy, and more breathing room between paragraphs.

improvementFollow-up Input Redesign

Replaced the explicit 'Ask' button with an inline send icon. Press Enter to submit, Shift+Enter for newlines.

improvementRoadmap Page Enhancements

Sticky progress header on scroll, expand/collapse all notes button, dynamic last-updated date, and empty state for community suggestions.

improvementResults Animation

Replaced word-by-word typing animation with a clean 300ms fade-in. Feels more professional and doesn't delay content access.