Skip to content

Redesign membership page + add Supporting Member tier - #523

Open
mohanadft wants to merge 25 commits into
mainfrom
feat/membership-v2-supporting-member
Open

Redesign membership page + add Supporting Member tier#523
mohanadft wants to merge 25 commits into
mainfrom
feat/membership-v2-supporting-member

Conversation

@mohanadft

Copy link
Copy Markdown
Collaborator

Summary

  • Rewrites /membership and /membership-new to match Kate's V2 design brief: headline, group photo, benefit list, Supporting Member callout, dues rationale, two CTAs, waiver small-print, and the home-new testimonial marquee.
  • Adds /supporting-member and /supporting-member-new for the new lower-commitment tier, with a benefits comparison table against full membership.
  • Qgiv stays embedded on-page in a #join section (rather than linking out to secure.qgiv.com) so the existing QGIV.donationComplete/api/membership-complete completion pipeline keeps working for both tiers.
  • /api/membership-complete now accepts an allowlisted tier field: supporting tags the contact Supporting Member in EmailOctopus and explicitly skips the Hub invite; anything unrecognized falls back to member (unchanged behavior for existing clients).
  • Fixes a latent bug where /membership-new's QGIV.donationComplete listener lived in a different component than the Qgiv embed itself, so it never fired — no Hub invites or EmailOctopus tags were happening on that page.
  • Extracts shared testimonial data (src/data/testimonials.ts) and membership benefit copy (src/data/membershipBenefits.ts) so both the legacy MUI design and the new design system render identical content.
  • -new pages are noindex and added to the sitemap exclude list in astro.config.mjs, per the existing -new page convention.

Test plan

  • Visual check of all four pages at mobile/tablet/desktop widths
  • #join anchor scroll lands correctly below the fixed navbar on both -new pages
  • Testimonial marquee pauses on hover and respects prefers-reduced-motion on all four pages
  • Dues calculator A/B test still assigns/persists correctly on /membership-new and /supporting-member-new
  • Submit a test Qgiv transaction on /membership-new#join and confirm /api/membership-complete fires with tier: "member"
  • Submit a test Qgiv transaction on /supporting-member-new#join and confirm the contact is tagged Supporting Member in EmailOctopus with no Hub invite
  • Confirm /supporting-member is present in the sitemap and /supporting-member-new is excluded
  • pnpm check and pnpm build pass (verified locally before push)

…tier

Rewrites /membership and /membership-new to Kate's V2 brief (headline,
photo, benefit list, dues rationale, waiver copy, testimonial marquee)
and adds matching /supporting-member and /supporting-member-new pages
for the new lower-commitment membership tier.

Qgiv stays embedded in an on-page #join section rather than linking
out, so the existing QGIV.donationComplete -> /api/membership-complete
pipeline keeps working. That endpoint now accepts an allowlisted tier:
supporting members are tagged "Supporting Member" in EmailOctopus and
explicitly skip the Hub invite, per the brief. Also fixes a bug where
/membership-new's donation-complete listener was orphaned from its
Qgiv embed and never fired.

Shared testimonial data and membership benefit copy are extracted so
both design systems (legacy MUI and the new design system) render the
same content.
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deploying website with  Cloudflare Pages  Cloudflare Pages

Latest commit: 2ddfd61
Status: ✅  Deploy successful!
Preview URL: https://3c4d50d9.website-aun.pages.dev
Branch Preview URL: https://feat-membership-v2-supportin.website-aun.pages.dev

View logs

Was centered via mx-auto; the brief calls for the photo sitting to the
left rather than centered in the column.
…pporting-member

# Conflicts:
#	public/_redirects
… table header

Widens /membership and /supporting-member from max-w-4xl to max-w-6xl and
moves the hero photo beside the opening copy instead of stacking it above,
so wide desktop viewports don't read as lopsided whitespace. Prose blocks
keep a readable max-w-[700px] cap; structural elements (CTAs, table, forms)
use the full width.

On /membership this also moves the intro paragraph and benefit list out of
MembershipPage.tsx (client:only, invisible until JS loads) into static
markup, extracting the list to src/data/membershipBenefits.ts alongside
the existing shared exports.

Also alternates the testimonial marquee between founder and member quotes
instead of grouping them, and drops the redundant "What you get" table
header on the Supporting Member comparison table.
…page width

scroll-behavior: smooth only existed scoped to html.no-js in
design-system.css, which the legacy Layout.astro (used by /membership and
/supporting-member) never loads — clicking "Become a member" jumped
straight to #join instead of scrolling. Added it globally in base.css,
which both layouts share, with a prefers-reduced-motion override back to
auto.

The testimonial marquee track was a sibling of the max-w-6xl container
instead of nested inside it, so it spanned the full viewport instead of
matching the rest of the page. Nested it using the same canceling-margin
pattern the design-system version already uses.
Replaces the generic Tailwind-template look (white bg, zinc-200 borders,
one flat green accent) with a warm paper palette, Fraunces/Outfit type
pairing (already defined in tailwind.config.mjs, previously only loaded
by the shelved -new design system), and a small recurring tri-color
hairline mark (green/ink/red, an abstracted nod to the flag palette used
only as a structural rule, never as flag imagery) opening each section.

Visual-only: no copy changes, no changes to routes/anchors, and no
changes to the Qgiv embed, dues A/B test, or EmailOctopus tiering logic
in QgivJoin/MembershipCalculator/LegacyJoinSection - only their styling.
PageHeader.astro and other shared/global files are untouched since they
back ~20 other live pages.
…ment

Enhances /membership and /supporting-member using only the palette
already in these files (white/zinc grayscale + the site's existing
#168039 green) and the inherited font stack — no new colors, no new
fonts, nothing carried over from the shelved -new design system.

- More vertical rhythm between sections
- Cards (fork card, waiver note, join-section panels, calculator) get
  slightly larger radii and green-tinted hover shadows
- CTAs/links get visible focus rings and pressed states, not just a
  flat hover color swap
- Comparison table rows highlight on hover
- Testimonial cards get a motion-safe hover lift (automatically off
  under prefers-reduced-motion; the existing animation/no-js fallback
  logic is untouched)
- Hero photos get a subtle ring/shadow for definition
- "10M+ Users Across 90+ Projects" sized as a real stat callout

Visual-only: no copy, route, or functional-logic changes (Qgiv embed,
dues A/B test, calculator math all untouched).
Adds a "Membership Join Click" event on the primary/secondary CTAs on
/membership and /supporting-member, filling the gap between the existing
pageview event and the Qgiv completion event so drop-off before vs. after
the CTA click can be distinguished.
Kate's request was specific to the Supporting Member flow. Removes the
"Membership Join Click" instrumentation from /membership (MembershipPage.tsx)
so the event only ever fires from the Supporting Member CTA on
/supporting-member.
Keep the section heading, intro, dues calculator, and sidebar visible
across both steps; only the Qgiv embed cell swaps between AboutYouStep
and QgivJoin. Drop the redundant "Inclusivity & waivers" sidebar box
(already covered by LegacyWaiverNote above) and fold the tax-deductible
note into the "Get in touch" box for both /membership and
/supporting-member.
…ng state

Unmounting QgivJoin when the visitor goes back to About You and forward
again re-ran its script-injection effect, re-adding Qgiv's embed.js tag.
The script throws a SyntaxError on redeclaration, breaking the embed.
Keep AboutYouStep/QgivJoin permanently mounted once payment is first
reached, toggling visibility with CSS instead of conditional rendering.

Also add a loading overlay (cleared via MutationObserver, with a
fail-open timeout) so the embed cell doesn't show blank white space
while Qgiv populates the container.
Qgiv's embed can populate the container within milliseconds when its
script is already cached, making the loading overlay flash and vanish
before a visitor notices it. Add a minimum display floor and swap the
plain text for a spinner so it reads as an actual loading state.
…insertion

The loading overlay was clearing as soon as Qgiv inserted its (still
empty) <iframe> into the container, before the iframe's cross-origin
document had actually finished loading. That left a second unguarded
blank gap while the iframe's own network request completed. Watch the
iframe's `load` event instead so the overlay covers the whole wait.
The About You form and the Qgiv payment embed differ a lot in height,
so switching between them (or the embed growing once it finishes
loading) caused an abrupt layout jump. Measure the visible child with
a ResizeObserver and animate the wrapper's height to match instead.
Replace the ResizeObserver-driven height animation with a plain fixed
height (matching QgivJoin's own max-height cap) applied to both the
About You form and the payment embed, so switching between them never
resizes the panel at all.
…t mismatch

Center the redirect note and Next button in AboutYouStep. Also fix
QgivJoin's loading overlay only reserving 400px internally while the
parent panel is fixed at 640px, which centered the spinner within the
shorter top portion instead of the full box.
Switch the loading-overlay wrapper from a Tailwind min-height bracket
class to an explicit inline height, matching the panel's fixed 640px
exactly, so the spinner centers within the same box the panel reserves
instead of a shorter box within it.
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.

1 participant