docs: reframe Rozenite positioning around React Native and Lynx - #496
Merged
Conversation
Rozenite reaches React Native, React Native Web and Lynx, but the landing page, the README and most of the docs still describe a React-Native-only product. This widens the framing everywhere it is now wrong, without overstating how far Lynx support actually goes. Landing page: - hero names both targets, with the rest of the breadth in a chip row rather than a third line of display type - new Rozenite for Lynx section, as the page's only ordered rail - new standalone app section, as its only centred full-width figure - Web and Build-your-own swap tints so the run keeps alternating - BrandMark grows multi-path support and a vendored Lynx mark Docs: - Lynx joins the compatibility matrix, pinned to the rspeedy and @lynx-js/react versions we actually test against - Rozenite for Lynx and for Web move under a Targets group, with redirects for the two URLs that moved - agent docs say "app" and "target" now that agents reach Lynx - Redux DevTools is corrected out of the Lynx-compatible list: its runtime statically imports react-native for trace symbolication - the standalone app is sold on its own merits rather than on React Native DevTools' shortcomings Refs #493 for the missing `rozenite init` Lynx detection, which the getting-started page now points at.
The section shipped with a ScreenshotSlot placeholder. The real capture is a raw window grab: it carries macOS traffic lights but no border or shadow, and a dark app screen sitting flush on the page reads as a hole rather than a window. So the section frames it -- hairline, `--rz-radius-surface` with `overflow: hidden` so the capture's square corners take the frame's radius, and a low diffuse shadow with its own dark-mode values, since a light-mode shadow vanishes against a dark ground. Nothing draws chrome the capture already has. Held to 80% of the measure. At full bleed it competed with the hero's screenshot, and holding it back keeps it nearer its native 1280px so it stays crisp on a 2x display. Full width below 560px.
Replaces the DevTools screenshot in the hero with `RozeniteLoader` from @rozenite/ui -- a Bayer-dithered light field masked to the Rozenite silhouette. Three details that are easy to get wrong: - It is imported from the workspace source through a single module in `landing/components`. @rozenite/ui exports only its barrel and declares no `sideEffects: false`, so importing through the package entry point would pull Base UI, TanStack Table and Virtuoso into a static docs bundle for one canvas. The website is never published, only bundled, so it reads the source directly and @rozenite/ui stays untouched. - The component is a loading spinner by origin, defaulting to `role="status"` with a "Loading" label. Here it is decorative, so it passes `label=""` rather than announcing that a settled page is loading. - Canvas cannot read CSS, so `fillStyle = 'var(--rz-accent)'` is silently ignored and paints black. `useTokenColor` resolves the token and re-resolves it when the theme flips. `landing-rozenite.png` is now imported by nothing and so emitted by no build. It is left in the tree in case the hero ever wants a product shot back.
The hero was a text-and-visual split: wordmark and copy on the left, a product shot on the right. With the mark as the visual it was carrying two Rozenite logos above the fold, and the split had nothing left to hold apart. Now it is one centred column -- mark, headline, lead, targets, actions, install -- and the static wordmark is gone, since the site navigation already carries one. The headline gets the full measure, so each of its two claims lands on one line at desktop width. The mark is sized in JS because the canvas takes its size as a number rather than from CSS. At the desktop size it pushed "Get started" past the fold on an 812px phone, so a narrow pair kicks in under 720px, with the grain scaled to match -- too fine for the height and the silhouette stops reading as the logo.
Roughly doubles the cell density: 30 to 56 cols at the desktop size, 22 to 38 at the narrow one. 56 is about as fine as this size survives. The loader insets every cell by `max(0.6, s * 0.09)` device px, so once cells approach 2 device px that fixed floor is most of the cell, the squares fall below a pixel and the mark washes out -- 88 cols does exactly that on a 1x display. The floor is in device pixels, so the same `cols` reads twice as solid at 2x as at 1x; both were checked. Noted in the landing README so the next person does not rediscover it by turning the dial.
The landing README documents the page's design conventions. The animated mark section documented a component's props instead, and every claim in it was already a comment on the code it described -- the workspace import in `components/rozenite-loader`, `label=""` and `useTokenColor` in `hero.tsx`, the size/grain pairing on the constants themselves. A second copy only drifts, and it already had: it named a `cols` value the code no longer used. It also stated a density ceiling measured on a 1x display as though it were general, when the floor it described is in device pixels and so sits twice as high on a 2x screen. Drops the section, keeps the one page-level fact in `## Motion` where the other two loops are already counted, and trims the same duplication out of the capture and brand-mark notes -- both now point at the file that carries the reasoning. The 1x/2x caveat moves to the constants it constrains.
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.
Description
Rozenite reaches React Native, React Native Web and Lynx, but the landing page, the README and most of the docs still describe a React-Native-only product. This widens the framing everywhere it is now wrong — without overstating how far Lynx support actually goes.
Landing page
BrandMarkgrows multi-path and per-iconviewBoxsupport so it can carry the Lynx mark.README — motto is now "Plug-and-play DevTools panels for React Native and Lynx". The compatibility table was also stale on its own terms (
1.xagainst a repo on 2.4.0); it is now split into React Native and Lynx tables and synced with the docs.Docs
@lynx-js/reactversions we actually test against.react-native.tsfilename is a real API and is unchanged.Related Issue
Closes #495
Context
Two corrections rather than rewordings.
rozenite-for-lynx.mdxlisted Redux DevTools among the plugins that work on Lynx. It does not:packages/redux-devtools-plugin/rozenite.config.tsdeclares['react-native', 'react-native-web'], and the runtime reachesreact-nativethrough a static, unguarded import chain —src/runtime.ts:14→symbolication/trace.ts:3→symbolication/metro.ts:1, which usesNativeModules.SourceCodeto find the Metro origin for trace symbolication. The config was right and the doc was wrong, so the doc moved. Worth noting for later: only the trace tab needs that import, and the UI already has an "unavailable" state for it, so making it lazy would plausibly unlock Lynx — separate work, not done here.Lynx compatibility no longer enumerates simulators and transports. How Rozenite reaches a device is an implementation detail, not a support boundary, and the old phrasing read as a shrinking list of caveats rather than support for a platform. The version table replaces it. The "Pin discovery to one device" section is untouched — that is configuration reference, and someone narrowing discovery genuinely needs it.
The Lynx mark has no
simple-iconsentry, so its two paths are vendored intocomponents/brand-markfrom lynxjs.org's own header — vendored rather than hotlinked, so the page pulls nothing from a third-party CDN. It is ByteDance/TikTok's mark, used nominatively to identify the project Rozenite integrates with. The Lynx repositories are Apache-2.0, whose section 6 grants no trademark rights, so this rests on nominative use rather than on the licence; rendering incurrentColoris part of that posture and is already the landing page's rule for every brand mark. This is reasoned out inwebsite/landing/README.md. A courtesy issue onlynx-family/lynxasking whether they are happy with the use has not been opened — flagging for a maintainer to decide.Two landing-page conventions changed deliberately, both written back into
website/landing/README.mdso the next person does not re-litigate them: eyebrows now cover four product surfaces rather than three (Lynx is a surface the way Web is; the standalone app is a way of working, so it has none), and the tint alternation is now documented as a rule since inserting a section means retinting its neighbours.Two URLs moved.
/docs/rozenite-for-lynxand/docs/rozenite-for-webare linked from package READMEs and npm, so permanent redirects are added inwebsite/vercel.jsonand all in-repo links are updated.No version plan. The only
packages/changes are the@rozenite/clidescription and README, which no longer describe a React-Native-only CLI. That is metadata and documentation, not behaviour.getting-started.mdxnow points Lynx users away fromrozenite init, which does not detect rspeedy projects — filed as #493.Testing
pnpm checks:affected— 84 tasks, all passing (typecheck, lint, oxfmt)pnpm test:affected— 48 tasks, all passingpnpm turbo run build --filter=@rozenite/docs— clean; verifiedbuild/docs/targets/contains both moved pages and that both new landing sections render intobuild/index.htmlManual verification of the built site, served locally and driven in the browser:
1.02fr / 1frand the display clamp capped at3.375rem)subtleone borderedcurrentColorNot verified: the Lynx docs' factual claims were not re-run against a live Lynx app — this change corrects the Redux entry from the plugin configs and source, and otherwise leaves the setup instructions as they were. The standalone section ships with a
ScreenshotSlotplaceholder; a real capture of the Electron window still needs taking.