Conversation
Discrete mouse wheel ticks (especially on Windows) caused visible stutter in the hero scrub. Insert an exponential smoother between window.scroll and the animation update so 100px wheel jumps blend over a few frames instead of hitting the video seek and CSS transforms in one step. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The hero animates on the smoothed clock while the content section below scrolls natively, so a wheel flick made the section's top edge race ahead of the video bottom and cut off the icon. Counter-translate the content wrapper by the same lag the smoother is closing — scrollbar stays honest, the visual edge stays glued. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A single tunable scales how much scroll is required to drive the hero animation. Default is 2 (half as sensitive as before). The scroll-distance quantities (runway height, icon-rise band) scale with the factor, while the icon's rest position stays anchored to its own height so scroll=0 still shows the same peek. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Mobile has native momentum scrolling that already produces smooth per-frame deltas; layering our easing on top fights the platform and shows up as jank. Detect (pointer: coarse) and snap to target on touch, same branch as prefers-reduced-motion. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
OG + Twitter card tags so shares on Slack/Discord/Twitter/LinkedIn render with title, description, and a 1200x630 image (og-image.png to be added separately). Sharpens the title to match the hero copy and adds canonical, theme-color, and a 256x256 apple-touch-icon copied from the existing icon. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
JPEG at 1200x630 comes in around 75KB vs ~1MB for the PNG with no visible quality loss at card sizes. Updates the four meta-tag URLs and adds og:image:type for spec compliance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restructure the "Take one for the road" section so the form lands right after the value pitch, with expectation-setting microcopy below it. Headline restates the outcome instead of punning, CTA names the thing the user is signing up for, and the dev-log identity is made explicit so subscribers aren't surprised by the Substack confirmation flow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Notify form: visible "Email" label, autocomplete hint, Roam-anchored success message, and microcopy demoted from prose-size to attached-to- form size so it reads as expectation-setting rather than another paragraph. Footer recentered and bumped to text-base; "Built by..." parenthetical wraps as a single chunk on narrow screens. Dependencies page distinguishes end-user vs marketing-page deps. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pages project's root directory is the repo root (build command `pnpm build:website`, output `website/dist`), so functions/ must live at the repo root, not under website/. Without this the Function silently isn't deployed and the endpoint 405s. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Functions directory moved to repo root in the prior commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
A 429 was hitting fresh emails because every signup egressed through the same Cloudflare Pages IP, putting all our users in one rate-limit bucket on Substack's side. Forwarding CF-Connecting-IP as X-Forwarded-For puts each end-user in their own bucket. Browser-like User-Agent and Accept headers also reduce the chance of tripping generic bot heuristics. Also surfaces the upstream status, error list, and a body preview in the error response (under _upstream) so we can see what Substack returns for cases like already-subscribed without redeploying. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Substack's no-JS endpoint refuses to disclose dedup state for
already-subscribed emails (returns "Please enable JavaScript"), and
will soft-block on rate limits or bot heuristics. None of these are
solvable from a server-side proxy. When we detect them, return
{fallback: true, fallbackUrl} and have the frontend redirect to
nedshed.dev/subscribe?email=... where Substack's full JS flow handles
everything cleanly.
Fresh-email happy path still subscribes inline. Only edge cases
redirect.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Substack's first-party subscribe endpoint blocks server-side proxies with a "Please enable JavaScript" anti-bot response for already- subscribed emails (and rate-limits suspicious egresses generally). Substack officially redirects integrators to Supascribe, which has a real Substack integration and handles validation, dedup, anti-bot, and the success state in a self-contained 108KB script. Net change: -269 / +22 lines. The Cloudflare Pages Function and the mirroring vite dev plugin are gone; the React form is replaced by a div + dynamic script tag. Embed config (button text, colors, success message, publication) lives in the Supascribe dashboard. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After exhausting proxy-based and embed-based options, ship the simplest reliable thing: keep our styled form, on submit redirect to nedshed.dev/subscribe?email=ENCODED. Substack's hosted page handles validation, dedup, and confirmation flow. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
After submit, replace the form with a spinner + "Just one more lick! Hit subscribe after the redirect..." where "the redirect" is a link to the same destination, letting impatient users skip the 3s wait. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.