Skip to content

Implement the GratiText Figma designs across marketing, auth, recipients, and settings - #98

Merged
kody-bot merged 13 commits into
mainfrom
cursor/figma-design-implementation-b50d
Sep 14, 2026
Merged

kody-bot merged 13 commits into
mainfrom
cursor/figma-design-implementation-b50d

Conversation

@kentcdodds

@kentcdodds kentcdodds commented Sep 14, 2026

Copy link
Copy Markdown
Member

Faithful implementation of the GratiText Figma designs (light, dark, and mobile frames).

  • Foundations: Fraunces + Poppins fonts, full light/dark color token set, type scale, pill inputs/buttons, select chevron, OTP slots, password show/hide field.
  • App chrome: new header (wordmark, upgrade CTA, user menu, theme toggle), footer, and mobile bottom-sheet menu with focus trapping.
  • Landing page: hero illustration, wave-edged feature section with flower stickers, "How it works" dashed path, pricing cards with smileys, CTA banner. Illustrations extracted from the Figma renders into public/images.
  • Auth: login, signup (country code + phone), verify (OTP), onboarding, forgot/reset password on a shared FormPage.
  • Recipients: list table with queue counts and trial banner, new/edit recipient form (country code, time zone, weekly day/time schedule with cron fallback, basic-plan reserved days), chat-style recipient thread with sent/scheduled bubbles, message action menu, autosizing composer, and sidebar.
  • Account settings: "Hi {name}!" overview with inline name/phone editing (?edit=), settings link list, and dialog-style sub-pages (DialogPage) for password, 2FA, and subscription that float over the inert overview on desktop and render as full pages with a back link on phones.

Landing page follow-up

  • Re-extracted the paper plane and CTA leaves/flower assets so they no longer carry fragments of neighbouring layers (dashed trail, input field edge, flower petal).
  • The plane now lives inside the trail SVG and the dashed path is traced from the design, so the tail connects and loops like the original.
  • Green band: true sine waves on both edges, no white gap above (the wave rises into the hero's cream), bottom wave no longer hidden behind the next section, stickers centred on the wave lines; straight bottom edge on phones as in the mobile frame.
  • "How it works", pricing and CTA re-measured against the frames (type scale, spacing, illustration placement, full-bleed CTA on phones, cream featured plan card in dark mode); footer sits on the cream band on the landing page.

Review follow-up

  • Bugbot: the landing CTA form sent phoneNumber to /signup, which ignored it. Signup now reads the query param to prefill the country code and number; logged-in visitors get a "Go to your recipients" link instead of the form.
  • Bugbot: the login field is labelled "Username or Phone Number" but still used UsernameSchema, which rejects +, spaces and dashes. It now uses a looser identifier schema (login() already matches phone numbers).
  • Bugbot: DialogPage set role="dialog"/aria-modal unconditionally and read the breakpoint once. A useMediaQuery hook now drives the role, aria-modal and the focus trap, so phones get a plain page and resizes stay in sync.

Test Plan

  • bun run typecheck, bun run lint, bun run test pass.
  • bunx playwright test (14 e2e tests) passes serially; settings-profile and 2fa tests updated for the inline edit / dialog flows.
  • Manual QA against the Figma frames at 1440 (light + dark) and 390 (mobile) for landing, auth, recipients, recipient thread, and settings.

Checklist

  • Tests updated
  • Docs updated

Screenshots

Figma frame on the left, implementation on the right.

Green wave section, Figma vs app
How it works with paper plane, Figma vs app
Pricing, CTA and footer, Figma vs app
Mobile landing, Figma vs app

Recipient thread, light
Settings with inline phone edit
Change password dialog
New recipient, dark
Mobile recipients list
Mobile settings

Open in Web Open in Cursor 

cursoragent and others added 6 commits September 14, 2026 17:24
- Add Fraunces/Poppins fonts and the Figma colour palette as semantic
  light/dark tokens with a matching type scale
- Restyle button, input, textarea, checkbox, label, OTP and form field
  components to the pill-shaped Figma components
- Rebuild header, footer, mobile menu and theme toggle per the designs
- Rebuild the marketing landing page with extracted illustration assets,
  wave dividers, flower stickers, pricing and CTA banner

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
- Centre Fraunces headline over a cream form card with right-aligned
  primary action; full-bleed beige layout with bottom action on phones
- Add PasswordField with show/hide toggle and eye icons
- Share the country-code list (with flags) between signup and recovery
- Let auth routes trim the header via a route handle

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
- Cream dashboard tint, table-style recipient list with column labels,
  bold weekday schedule, prepared-message counts and Manage buttons;
  card layout on phones
- Full-bleed trial banner in the recipients layout and tier-aware header
  CTA / user menu (basic plan gets the orange upgrade button)
- Recipient editor rebuilt on the shared FormPage shell with country code
  select, labelled time zones, weekly day/time pickers (with a cron
  fallback), pause/resume pill and reserved days on the Basic plan
- Edit route no longer nests inside the recipient detail layout

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds marked this pull request as ready for review September 14, 2026 18:53

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread app/routes/_app+/_marketing+/index.tsx Outdated
cursoragent and others added 4 commits September 14, 2026 19:58
The paper plane carried part of the Figma dashed trail and a translucent
smear from misaligned light/dark frames; the CTA leaves carried a sliver
of the input field and a petal of the neighbouring flower. Re-cut all
three from the light frame with tight regions and fixed palettes.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
- Draw a true sine (7 periods desktop, 2.5 on phones) with the crest
  phase from the design
- Raise the divider above neighbouring sections so the bottom wave is
  no longer painted over by the section that follows
- Overshoot the section edge by 1 unit to avoid hairline gaps

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
- Remove the white gap above the green band by letting the wave rise
  into the hero's own padding; centre both stickers on the wave lines
- Anchor the paper plane inside the trail SVG and use a path traced from
  the design so the tail connects and loops like the original
- Scale up the How-it-works numbers, titles and body copy, and space the
  steps to the design's grid; use the 3rem section heading and 17px body
- Place the CTA illustrations from measured positions; full-bleed banner
  on phones with the leaves strip visible
- Pricing: narrower plan rows, smileys around (not over) the heading,
  cream featured card and outline basic button in dark mode
- Footer sits on the cream pricing band for the landing page

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
The previous extraction region clipped the right and bottom petals; the
wider region also picks up the banner's rounded corner, so pixels that are
a blend of the banner colour and the page cream are dropped.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stale Bugbot comment from a previous run.

Comment thread app/routes/_app+/_auth+/login.tsx
Comment thread app/components/dialog-page.tsx
cursoragent and others added 3 commits September 14, 2026 20:22
The bottom "Get started" form sent phoneNumber to /signup, which ignored
it. Signup now reads the query param to prefill the country code and
number. Logged-in visitors get a link to /recipients instead of the form,
matching the hero CTA.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
The field is labelled "Username or Phone Number" and login() already
looks up phone numbers, but UsernameSchema rejected "+", spaces and
dashes client-side.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Track the md breakpoint with a media-query hook so role="dialog",
aria-modal and the focus trap follow the viewport instead of a one-off
read at render time.

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds

Copy link
Copy Markdown
Member Author

bugbot run

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit d7c8cfd. Configure here.

@kody-bot
kody-bot merged commit 15385c4 into main Sep 14, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants