feat: reader modal install prompt demo (mockup)#6052
Open
tsahimatsliah wants to merge 17 commits into
Open
Conversation
DEMO ONLY: reshape the reader_modal experiment into a two-step flow for team review. Force-enable the experiment, route card clicks to the classic post modal, gate the "Read post" CTAs behind a new Nikita-Bier- style install pop-up, and resize / swap sides on the reader modal so the iframe sits on the left and the rail (TL;DR only, title dropped) sits on the right. Not intended to ship as-is; engineering will build the production version in a separate PR. Co-authored-by: Cursor <cursoragent@cursor.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Move close (X) from the iframe preview header to the engagement rail
header next to the three-dots menu in modal mode. The iframe header
keeps the X only when the rail is collapsed so users always have an
escape hatch.
- Re-enable shouldUseReaderLayout on /posts/[id] and cap the reader
page container to min(95vw, 118rem) centered, so the preview no
longer stretches edge-to-edge on large monitors and matches the
modal's footprint.
- Redesign the install prompt as a full-height reader-mimicking shell:
- URL bar header with favicon + permalink (click to copy) on the left
- Disabled three-dots + X cluster on the right
- Two-column body: blurred fake article on the left, mocked rail on
the right, install card overlaid in the center
- Card copy and visual hierarchy reworked: badge, headline that
promises the outcome, bullet list, primary install CTA, secondary
preview CTA, and a trust microcopy line
Co-authored-by: Cursor <cursoragent@cursor.com>
- Bump default rail ratio (0.30 → 0.36) so the engagement rail starts
with more breathing room without a manual drag.
- Bump reader modal + standalone post page max-width to min(96vw,132rem)
for a more theater-sized reading shell on large displays.
- Redesign install prompt as a believable in-app browser: tab strip with
traffic lights, back/forward/refresh, lock + permalink address bar,
bookmark/menu/close. Drop the engagement rail and the misleading
"Free. Works offline." microcopy. Sharper Nikita-Bier copy:
"Read this inside daily.dev? Install the extension and {host} opens
right here — no new tab, no context switching."
Co-authored-by: Cursor <cursoragent@cursor.com>
…all prompt
Reader modal / post page:
- Cap width at min(96vw, 76rem) so the article + rail stay legible and
centered instead of stretching across ultrawide monitors.
- Lock rail to 380px and remove the drag-to-resize PaneDivider so the
layout is deliberate (preview ~720-760px, rail 380px).
Install prompt:
- Collapse the two-row faux chrome (tab strip + URL bar) into one single
browser bar: traffic lights, back/forward/refresh, URL pill (lock +
favicon + permalink + star), menu, close.
- Replace the empty placeholder block with a full-width article preview
that uses the real post title, source name/avatar, hero image, and
read time. Only the body paragraphs stay blurred, so the surface
reads as "we opened your article inside daily.dev".
- Drop the em-dash in the install card subtitle: now reads
"Install the extension and {host} opens right here inside daily.dev.
No new tab. No context switching."
- Match install modal width to reader modal width so the
install → preview transition feels like just removing the overlay.
Co-authored-by: Cursor <cursoragent@cursor.com>
- MainLayout was adding `laptop:!pl-60` (240px expanded-sidebar inset) because the post page had `screenCentered: false`. That offset pushed the reader shell off-center and made the engagement rail anchor to the right edge of the viewport. Flipping the page to `screenCentered: true` removes the inset so the shell can center on the viewport like the modal portal does. - Move the 76rem width cap + mx-auto centering INSIDE `ReaderPostLayout` itself (on a new inner wrapper) so the shell is always capped to the modal's footprint regardless of what the outer `outerClassName` does. The page now only sets viewport-height bounds via `outerClassName`. - Net result: post page and modal render the exact same shell at the exact same width and behavior. Co-authored-by: Cursor <cursoragent@cursor.com>
… opaque card
- Force inner wrapper to w-full and add !w-full on the modal class so
the prompt actually fills the modal width instead of shrinking to
content.
- Browser chrome is now obviously a mockup:
- drop the three-dots / menu button entirely
- URL pill is a rounded rectangle (rounded-10) instead of an oval
pill; lock + star icons removed; just favicon + URL
- back / forward / refresh rendered as aria-hidden spans at low
opacity so they read as decoration, not clickable controls
- only the close (X) button stays interactive
- Background preview is now a heavily blurred (18px) abstract layout —
no real title, source, or cover image to compete with the install
card. Gradient overlay biases toward the page background so the
card pops.
- Overlay card is fully opaque (`bg-background-default`, no backdrop
blur, no /95 translucency) and gets a stronger shadow, so the
heading is always crisp regardless of what's behind it.
Co-authored-by: Cursor <cursoragent@cursor.com>
…u, prominent CTAs - Surface "Back to feed" inside the article preview header on the post page (left of the URL/favicon) via a new `leftHeaderActions` prop on `ArticleReaderFrame`. The rail header no longer renders its own back button. - Add `border-l` to the article column so the shell has a visible left edge that matches the rail's `border-l` on the right. - On the standalone post page, drop the rail's sticky header entirely and move `PostMenuOptions` inline next to the source's Follow button via a new `inlineHeaderMenu` prop on `EngagementRail`. The modal keeps its existing sticky header (three-dots + close). - Make the `NewComment` composer the obvious discussion entry point: BlueCheese-accent border, action-comment surface, larger avatar, taller hit area, and a soft shadow so it can't be missed. - Beef up `ReaderFloatingActionBar`: medium-size icons, h-11/w-11 buttons, gap-2 between actions, px-3/py-2 padding, rounded-20 pill so the bar reads as the primary "react to this post" surface instead of a thin chip. Co-authored-by: Cursor <cursoragent@cursor.com>
Context: user has just installed the extension, returned to daily.dev,
and lands inside the iframe asking for embedded-browsing permission.
The previous screen ("Enable embedded browsing" / "Enable for this
browser" / "I'd rather not read inside daily.dev") read as a generic,
slightly intimidating second ask after the install. Rewrite the copy
in the Nikita-Bier register: continuation, not obstacle.
- Permission prompt (`packages/extension/src/frame/render.ts`):
- Heading: "One tap to read in here."
- Body: "Turn on embedded browsing and articles open right inside
daily.dev. No new tabs, no bouncing around."
- Reassurance: "We only use it on links you open from daily.dev."
- Primary CTA: "Let's do it" (was "Enable for this browser")
- Secondary CTA: "Maybe later" (was "I'd rather not read inside
daily.dev")
- Dynamic status lines warmer: "Just a sec…", "You're in.
Reloading…", etc.
- Secondary button is now a real floating button (subtle bg +
1px border, matching the primary's dimensions) instead of a
transparent text link, so it reads as a clear escape hatch.
- Web fallback install prompt (`EmbeddedBrowsingWebPrompt.tsx`):
- Heading: "Read this inside daily.dev." (matches the install
modal so the journey feels cohesive)
- Body: shorter, value-first copy
- Opt-out switched from `Tertiary` text button to `Float` button
sized to match the install CTA.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Drop traffic-light circles from the install prompt browser bar
- Repaint the backdrop as a heavily blurred white article page with
richer skeleton content so it reads as a real webpage behind glass
- Sharpen the install prompt copy in a Nikita-Bier register
("Stop opening tabs.")
- Bump reader modal + post page max width to min(96vw, 88rem)
- Flatten the comment composer (neutral surface, slight border,
no shadow)
- Wrap the post-page "Back to feed" button in the same chrome group
as the eye toggle so they match visually
- Show "Close browser mode" label on the eye toggle inside the modal,
keep icon-only on the standalone post page
Co-authored-by: Cursor <cursoragent@cursor.com>
Make the secondary opt-out button read clearly as a button: transparent background with a 1.5px visible outline instead of a near-invisible 6% white fill that looked like plain text. Co-authored-by: Cursor <cursoragent@cursor.com>
Swap "Stop opening tabs." for "Read it right here." — invitational rather than pain-led, with a positive follow-up that highlights the benefit (article + discussion side by side). Co-authored-by: Cursor <cursoragent@cursor.com>
- Reader modal, install prompt and post page all share max width of min(96vw, 100rem) so the three surfaces render the same shell size - Install prompt gets a third action: "Open the article in a new tab" for users who want the regular new-tab behavior. Routes around the install + preview flow entirely and logs ClickReaderInstallSkip. - Eye toggle label inside the modal shortened to "Classic view" (was "Close browser mode") — clearer and shorter - Comment composer scaled down: Medium avatar, p-2, callout type so the rail stops being dominated by an empty CTA Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the asymmetric `pt-3 pb-2` with a symmetric `py-2` and lock a min height (3.25rem / 52px) on the URL row so the back button, favicon, URL and right-side chrome groups all sit on the same baseline in both the modal and the post page. Co-authored-by: Cursor <cursoragent@cursor.com>
ModalSize.XLarge applies a fixed `tablet:w-[69.25rem]` (1108px) which silently overrode our `tablet:!max-w-[min(96vw,100rem)]` cap — the modal was stuck at 1108px regardless of the requested width while the post page rendered at 1382px+ on the same viewport. Add an `!important` `tablet:!w-[min(96vw,100rem)]` alongside the existing max-w so width and max-width line up, and the modal actually fills the same shell as the post page. Co-authored-by: Cursor <cursoragent@cursor.com>
Align the web and extension embedded-reader prompts, switch the reader layout toggle to the globe icon, rename the reader exit action to "Close preview", make the new-tab escape opt out of future prompts, and match the preview and rail header heights. Co-authored-by: Cursor <cursoragent@cursor.com>
Replace the stripe animation in both web and extension prompts with a subtle ambient glow/pulse, tighten prompt width to avoid awkward subtitle wraps, and make the secondary escape explicit: "Don't ask again, open new tab". Co-authored-by: Cursor <cursoragent@cursor.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.
Summary
This PR is a non-production mockup for design review and screen recording. Engineering will build the real version in a separate PR — the changes here are scoped to the
reader_modalexperiment and gated by// DEMO ONLYcomments.Three changes:
ReaderInstallPromptModal) — blurred fake reader-preview background, Nikita-Bier-style headline + body, primaryInstall Chrome/Edge extensionCTA, secondaryPreview the experienceCTA (demo-only path into the reader modal), tertiaryopen in new tabescape hatch. Reuses existing log events.min(95vw, 118rem)), iframe swapped to the LEFT, engagement rail (TL;DR + tags + comments) swapped to the RIGHT, and the redundant title heading removed from the rail since the iframe shows the page title.The reader experiment is force-enabled at
useReaderModalEligibilityso demo recordings don't depend on GrowthBook assignment.Out of scope (do not implement from this PR)
Preview the experienceCTA is a screen-recording aid onlyEmbeddedBrowsingWebPromptinline panel (the rail-fallback path) is intentionally left untouchedTest plan
node ./scripts/typecheck-strict-changed.jspassespnpm --filter shared lintpassespnpm --filter webapp lintpassesPreview the experiencefrom the install pop-up opens the reader modal with the new layout/posts/[id]direct links also show the classic page with Read post CTAMade with Cursor
Preview domain
https://feat-reader-modal-install-prompt.preview.app.daily.dev