Overview
This issue is independent — it can be worked in parallel with any other issue. No contracts, SDK, or live data required.
Polish the frontend for production quality: skeleton loading screens, error boundaries, a custom 404 page, mobile optimisation, PWA support, dark/light mode toggle, and fixing a commented-out UI element.
Problem
The app currently lacks standard production-quality UI infrastructure:
- No loading states — data-fetching pages will show blank content while RPC calls complete
- No error boundaries — an uncaught error in any component crashes the entire page with no recovery option
- No 404 page — navigating to an unknown route shows a plain Next.js default
- Hero badge commented out —
app/src/app/page.tsx line 43: {/* <div className={styles.heroBadge}>Live on Stellar · Soroban</div> */} — this is commented out but the CSS class heroBadge is fully defined in page.module.css
- No PWA support — no
manifest.json, no service worker
- No dark/light mode toggle — the app is dark-only (
background: #060810 in globals.css)
- No OpenGraph image —
app/src/app/layout.tsx sets title and description metadata but no og:image, causing social share cards to appear blank
Proposed Solution
1. Skeleton loading screens
Create a app/src/components/Skeleton.tsx component (CSS shimmer animation). Apply to:
- Portfolio position cards while
usePosition is loading
- Analytics stat cards while
useTVL / useAPY is loading
- Allocation table rows while
useAllocations is loading
2. Error boundary (app/src/components/ErrorBoundary.tsx)
A React class component that catches render errors. Wrap all data-heavy pages. Show: Something went wrong — try refreshing, or check your wallet connection. with a Retry button.
3. Custom 404 page (app/src/app/not-found.tsx)
A branded 404 page matching the dark theme. Include the YieldLadder logo, a Page not found message, and a link back to the homepage.
4. Enable the hero badge
Uncomment line 43 in app/src/app/page.tsx:
<div className={styles.heroBadge}>Live on Stellar · Soroban</div>
This CSS class and all its styles are already defined in app/src/app/page.module.css — just uncomment.
5. Mobile optimisation audit
Test and fix the deposit flow (/deposit), portfolio (/portfolio), and analytics (/analytics) pages on 375px and 390px viewports. Add any missing breakpoints to the relevant CSS Module files.
6. PWA (app/public/manifest.json + service worker)
Add manifest.json with app name, icons, and display: standalone. Register a service worker for offline-capable asset caching (not data caching — RPC calls should always be live).
7. Dark/light mode toggle
Add a sun/moon icon toggle in the nav. Persist preference to localStorage. Use CSS custom properties (variables) in globals.css for all colours so toggling a data-theme attribute on <html> switches the palette.
8. OpenGraph image
Create app/public/og-image.png (1200×630px) with the YieldLadder branding. Add to layout.tsx:
openGraph: { images: [{ url: '/og-image.png', width: 1200, height: 630 }] }
Acceptance Criteria
Overview
This issue is independent — it can be worked in parallel with any other issue. No contracts, SDK, or live data required.
Polish the frontend for production quality: skeleton loading screens, error boundaries, a custom 404 page, mobile optimisation, PWA support, dark/light mode toggle, and fixing a commented-out UI element.
Problem
The app currently lacks standard production-quality UI infrastructure:
app/src/app/page.tsxline 43:{/* <div className={styles.heroBadge}>Live on Stellar · Soroban</div> */}— this is commented out but the CSS classheroBadgeis fully defined inpage.module.cssmanifest.json, no service workerbackground: #060810inglobals.css)app/src/app/layout.tsxsets title and description metadata but noog:image, causing social share cards to appear blankProposed Solution
1. Skeleton loading screens
Create a
app/src/components/Skeleton.tsxcomponent (CSS shimmer animation). Apply to:usePositionis loadinguseTVL/useAPYis loadinguseAllocationsis loading2. Error boundary (
app/src/components/ErrorBoundary.tsx)A React class component that catches render errors. Wrap all data-heavy pages. Show:
Something went wrong — try refreshing, or check your wallet connection.with a Retry button.3. Custom 404 page (
app/src/app/not-found.tsx)A branded 404 page matching the dark theme. Include the YieldLadder logo, a
Page not foundmessage, and a link back to the homepage.4. Enable the hero badge
Uncomment line 43 in
app/src/app/page.tsx:This CSS class and all its styles are already defined in
app/src/app/page.module.css— just uncomment.5. Mobile optimisation audit
Test and fix the deposit flow (
/deposit), portfolio (/portfolio), and analytics (/analytics) pages on 375px and 390px viewports. Add any missing breakpoints to the relevant CSS Module files.6. PWA (
app/public/manifest.json+ service worker)Add
manifest.jsonwith app name, icons, anddisplay: standalone. Register a service worker for offline-capable asset caching (not data caching — RPC calls should always be live).7. Dark/light mode toggle
Add a sun/moon icon toggle in the nav. Persist preference to
localStorage. Use CSS custom properties (variables) inglobals.cssfor all colours so toggling adata-themeattribute on<html>switches the palette.8. OpenGraph image
Create
app/public/og-image.png(1200×630px) with the YieldLadder branding. Add tolayout.tsx:Acceptance Criteria
/unknown-routerenders the custom branded 404 pageLive on Stellar · Soroban)manifest.jsonpresent; app is installable as PWA on Android Chromeog-image.pngwhen the URL is shared