Merge pull request #318 from MeshJS/claude/landing-stop-after-fade
perf(landing): stop the background animation only after it fully fades out
perf(landing): stop the background animation only after it fully fades out
feat(landing): reduce the mouse-over effect on the background
Builds on dropping the pause-on-scroll: instead of stopping the animation while scrolling (jarring), keep it running the whole time it's visible or fading, and only stop it once it has fully faded out — a beat later (~800ms), when it's invisible so the stop is imperceptible. PageHomepage sets data-bg-hidden on <html> ~800ms after the scroll fade reaches 0 opacity, and clears it instantly the moment the background starts fading back in. While the flag is set the marble shader skips its draws and the aurora's animations are paused (globals.css). Net: smooth continuous motion whenever you can see it, zero GPU spent on it once it's gone. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The cursor reactivity was a touch strong. Dial both effects down: - aurora orb parallax offset 26/22px → 10/8px - marble cursor swell amplitude 0.18 → 0.07 with a tighter falloff (exp -3.5 → -4.5), so it affects a smaller area more subtly Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Builds on dropping the pause-on-scroll: instead of stopping the animation while scrolling (jarring), keep it running the whole time it's visible or fading, and only stop it once it has fully faded out — a beat later (~800ms), when it's invisible so the stop is imperceptible. PageHomepage sets data-bg-hidden on <html> ~800ms after the scroll fade reaches 0 opacity, and clears it instantly the moment the background starts fading back in. While the flag is set the marble shader skips its draws and the aurora's animations are paused (globals.css). Net: smooth continuous motion whenever you can see it, zero GPU spent on it once it's gone. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
perf(landing): keep the background animating during scroll (drop pause-on-scroll)
The earlier pass paused the marble shader and froze the aurora animations while scrolling (html[data-scrolling]) as a belt-and-suspenders measure. It works but the animation visibly stops on scroll, which feels worse than a continuous one. The real performance came from the other changes — low-res + 30fps marble, no backdrop-blur over the canvas, static aurora base layers, no mix-blend, no will-change on the hero layers. Those make the whole background cheap enough to keep animating during scroll: the aurora orbs/sheen/bloom are transform/opacity (compositor-only), and the marble at 0.6x scale + 30fps has plenty of GPU headroom. So just remove the pause: - marble loop: drop the data-scrolling skip (keep the 30fps cap + tab-hidden pause) - homepage onScroll: drop the data-scrolling flag toggling (keep the rAF fade) - globals.css: drop the html[data-scrolling] animation-play-state:paused rule Net: the animation runs smoothly and continuously, including while scrolling. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
extractCidPath ran `s.match(/\/ipfs\/(.+)$/i)` on caller-supplied strings
(anchor URLs, CIDs). As a search-anywhere pattern it retries `/ipfs/` at many
start positions with a backtracking `.+$`, which CodeQL flags as polynomial
ReDoS on hostile inputs like "/ipfs/a/ipfs/a/ipfs/a…".
Replace it with a linear `indexOf("/ipfs/")` + `slice`, preserving the exact
behavior (everything after the first "/ipfs/" segment that has content,
case-insensitive). Add an extractCidPath test covering the equivalence cases
plus a hostile-input case that must terminate quickly.
Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
perf(landing): cut continuous GPU cost for butter-smooth scrolling
The rAF/ref scroll fade wasn't the real bottleneck — the landing ran two GPU-saturating things every frame, even idle: - MarbleField is a full-viewport WebGL shader (5-octave fbm, double domain warp) on an unthrottled rAF loop at up to 1.5x DPR. - A backdrop-blur pane sat over that live canvas (re-blur every frame), and the aurora animated background-position on 300%-size, 40-64px-blurred layers (continuous repaints) plus mix-blend-soft-light. Changes: - Marble: render the backing store at ~0.6x scale, DPR capped at 1 (~5x fewer fragments); cap the loop to ~30fps; skip all shader work while the tab is hidden or the user is scrolling. Look is unchanged (it sits under a soft wash). - Drop the backdrop-blur frost pane → a plain translucent wash (the low-res marble already reads soft). - Aurora: make the two base gradient layers static (kills the background-position repaints) and drop mix-blend-soft-light. Life now comes only from the transform/opacity orbs, sheen and bloom, which composite cheaply. - Remove will-change:opacity from the two full-viewport hero layers (it forced giant permanent compositor layers and hurt more than helped). - Pause the aurora's compositor animations (and the marble) while actively scrolling via an html[data-scrolling] flag, resuming ~140ms after scroll stops. Net: near-zero idle cost and the GPU is free during scroll. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
perf(landing): smooth scroll by driving hero fade via rAF + refs
style(theme): extend glass-morphism to all cards
refactor(ui): unify Overview copy affordance + signer button hierarchy
The landing recomputed aurora/marble opacity from a scrollY React state set on every scroll event, re-rendering the whole (large) homepage tree each frame — the main source of choppy scrolling. On top of that, a 700ms opacity transition fought the frequent updates, smearing the fade. Now the two fixed background layers are updated by writing opacity straight to their DOM nodes (refs) inside a requestAnimationFrame callback. Scrolling no longer triggers any React re-render; the transition is removed (per-frame rAF updates are already smooth) and the layers get will-change: opacity so the compositor handles the fade. Behavior (fade 500→1500px) is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
The glass design system (.glass-nav/.glass-card/.glass-subtle) was already applied to the header and sidebar, but the shared Card surface stayed opaque (bg-white / dark:bg-zinc-950). Make Card a glass surface — translucent + backdrop blur — so the (now default-on) animated background shows through and the whole platform reads as one glass theme. Opacity is kept high (80% light / 60% dark) to preserve text contrast on content-dense cards; call sites can still override the bg via className. This propagates to every CardUI/Card across the app via the one shared component. Nested content surfaces (stat tiles, list rows) intentionally stay solid — glass-over-glass blur is muddy and GPU-heavy; solid blocks on a glass container is the correct pattern. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
feat(appearance): default animated background on + show it on the homepage
docs(agents): point to the vault as the source of specs/PRDs
Make the wallet Overview more uniform: - ui/RowLabelInfo now shows an explicit copy icon (with copy→check feedback) next to the value, instead of hiding copy behind making the whole value a ghost button. This matches the affordance already used in the signers list, so every address/hash row copies the same way. Copyable values render in font-mono for consistency. - Signer rows: "Connect Discord" becomes a secondary (outline) button so each row has one primary action (Verify) + one secondary, instead of two solid buttons side by side. - Remove an unused duplicate RowLabelInfo import in card-info. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
- Default backgroundEnabled to true (was opt-in off). - Render the setting-driven app background on every route, including the homepage (removed the !isHomepage exclusion) — it sits behind the homepage's own hero background and persists as that one fades on scroll. - The homepage hero background now follows the same toggle + selected preset (with a mounted guard so SSR and first client paint agree). Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Adds a "Specs & PRDs" section to .agents/README.md: features are specified as PRDs in the maintainer's document-driven vault before they are built, entity notes are the spec for their Prisma models, and implementing PRs should cite the PRD id so code stays traceable to the document that produced it. Closes the doc<->code loop from the code side. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
feat(appearance): opt-in animated app background with selectable styles
Adds a profile → Appearance setting to run the animated aurora background behind the app, plus a picker of colour themes for customization. - New persisted (localStorage) appearance store: backgroundEnabled + backgroundPreset. - Background component gains a `preset` prop (Aurora / Sunset / Ocean / Nebula / Monochrome) driving the orb / sheen / bloom colours; grayscale base + reduced- motion handling unchanged. BACKGROUND_PRESETS is the single source of truth. - Mounted in the app layout as a fixed -z-10 layer, gated on the toggle and skipped on the marketing homepage (which has its own background). A mounted guard avoids an SSR/localStorage hydration mismatch. - Profile "Appearance" card: a Switch toggle + a preset picker with live static swatches (disabled until enabled). - New dependency-free Switch UI primitive (shadcn checked/onCheckedChange API). Default is OFF, so existing users see no change until they opt in. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
Bumps [eslint-config-next](https://github.com/vercel/next.js/tree/HEAD/packages/eslint-config-next) from 16.2.6 to 16.2.9. - [Release notes](https://github.com/vercel/next.js/releases) - [Changelog](https://github.com/vercel/next.js/blob/canary/release.js) - [Commits](https://github.com/vercel/next.js/commits/v16.2.9/packages/eslint-config-next) --- updated-dependencies: - dependency-name: eslint-config-next dependency-version: 16.2.9 dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] <[email protected]>
Bumps [tailwindcss](https://github.com/tailwindlabs/tailwindcss/tree/HEAD/packages/tailwindcss) from 3.4.19 to 4.3.1. - [Release notes](https://github.com/tailwindlabs/tailwindcss/releases) - [Changelog](https://github.com/tailwindlabs/tailwindcss/blob/main/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/tailwindcss/commits/v4.3.1/packages/tailwindcss) --- updated-dependencies: - dependency-name: tailwindcss dependency-version: 4.3.1 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]>
Bumps [lucide-react](https://github.com/lucide-icons/lucide/tree/HEAD/packages/lucide-react) from 0.439.0 to 1.18.0. - [Release notes](https://github.com/lucide-icons/lucide/releases) - [Commits](https://github.com/lucide-icons/lucide/commits/1.18.0/packages/lucide-react) --- updated-dependencies: - dependency-name: lucide-react dependency-version: 1.18.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <[email protected]>