···2233## Project Structure & Module Organization
4455-- `src/routes` contains SvelteKit routes, including dynamic handle pages in `src/routes/[handle]/[[page]]`, edit flows in `src/routes/[handle]/[[page]]/edit` and `src/routes/edit`, and API endpoints under `src/routes/api`.
66-- `src/lib` holds reusable modules: card implementations in `src/lib/cards`, shared UI in `src/lib/components`, OAuth helpers in `src/lib/oauth`, and site data/loading in `src/lib/website`.
55+- `src/routes` contains SvelteKit routes. User-facing pages are under `src/routes/[[actor=actor]]/(pages)/` with an optional actor param (double brackets). When omitted, the actor is resolved from custom domain KV or `PUBLIC_HANDLE`. API endpoints live under `src/routes/api` and `src/routes/[[actor=actor]]/api`.
66+- `src/lib` holds reusable modules: card implementations in `src/lib/cards`, shared UI in `src/lib/components`, ATProto/OAuth helpers in `src/lib/atproto`, and site data/loading in `src/lib/website`.
77- Root app setup lives in `src/app.html` and `src/app.css`.
88- `static` is for public assets served as-is.
99- `docs` includes contributor-facing docs like custom cards and self-hosting.
+13-7
CLAUDE.md
···6161- See e.g. `src/lib/cards/EmbedCard/` and `src/lib/cards/LivestreamCard/` for examples of implementation.
6262- Cards should be styled to work in light and dark mode (with `dark:` class modifier) as well as when cards are colorful (= bg-color-500 for the card background) (with `accent:` modifier).
63636464-**ATProto Integration (`src/lib/oauth/`):**
6464+**ATProto Integration (`src/lib/atproto/`):**
65656666- `auth.svelte.ts` - OAuth client state and login/logout flow using `@atcute/oauth-browser-client`
6767- `atproto.ts` - ATProto API helpers: `resolveHandle`, `listRecords`, `getRecord`, `putRecord`, `deleteRecord`, `uploadImage`
6868- Data is stored in user's PDS under collection `app.blento.card`
6969- **Important**: ATProto does not allow floating point numbers in records. All numeric values must be integers.
7070+- Login redirect: before OAuth redirect, the current path is saved to `localStorage` (`login-redirect`) and restored after callback
70717172**Caching (`src/lib/cache.ts`):**
7273···88898990### Routes
90919191-- `/` - Landing page
9292-- `/[handle]/[[page]]` - View a user's bento site (loads from their PDS)
9393-- `/[handle]/[[page]]/edit` - Edit mode for a user's site page
9494-- `/edit` - Self-hosted edit mode
9595-- `/api/links` - Link preview API
9292+All user-facing pages live under `src/routes/[[actor=actor]]/(pages)/` using an optional `[[actor=actor]]` param. When the actor param is omitted, the layout resolves the actor from a custom domain (via KV lookup) or the `PUBLIC_HANDLE` env var.
9393+9494+- `/` - Landing page (or a user's site when on a custom domain)
9595+- `/[actor]` - View a user's bento site (loads from their PDS)
9696+- `/[actor]/edit` - Edit mode for a user's main page
9797+- `/[actor]/p/[page]` - View a named sub-page
9898+- `/[actor]/p/[page]/edit` - Edit mode for a sub-page
9999+- `/[actor]/p/[page]/copy` - Copy a page to your own site
100100+- `/[actor]/og.png` - Dynamic OG image generation
101101+- `/[actor]/api/refresh` - Cache refresh endpoint
102102+- `/[actor]/.well-known/site.standard.publication` - Site publication metadata
96103- `/api/geocoding` - Geocoding API for map cards
9797-- `/api/reloadRecent`, `/api/update` - Additional data endpoints
9810499105### Item Type
100106
+2
src/lib/atproto/auth.svelte.ts
···126126 scope: metadata.scope
127127 });
128128129129+ localStorage.setItem('login-redirect', location.pathname + location.search);
130130+129131 // let browser persist local storage
130132 await new Promise((resolve) => setTimeout(resolve, 200));
131133