Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude/launch.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
{
"version": "0.0.1",
"configurations": [
{
"name": "web",
"runtimeExecutable": "pnpm",
"runtimeArgs": ["--filter", "@atrium/web", "dev"],
"runtimeArgs": ["--filter", "@ourspace/web", "dev"],
"port": 5173
}
]
Expand Down
134 changes: 134 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
Working title: Atrium (placeholder — see Naming at the bottom)

What this is

A portfolio-first social platform for artists and creators — the intersection
of LinkedIn and Instagram with forum features later, built to remove
liminality rather than farm engagement. Every person is represented by a
low-poly avatar they build themselves; every profile is a warm, curated page
of modules showing their work; and their image-based modules can be entered
as small 3D spaces, walked through in third person like a private gallery.
Reference feeling: https://thevertmenthe.dault-lafon.fr/ — quiet, personal,
the art is the point.

Product principles (non-negotiable)

1. Profile-first, never feed-first. The unit of the platform is a person's
space, not a stream of content. Discovery happens by visiting people.
2. Warm, not liminal. Every surface should feel inhabited and intentional —
a studio apartment, not an airport.
3. Documents are parameters, not meshes. An avatar is a compact JSON document
(AvatarDoc); a profile is a compact JSON document (ProfileDoc). Rendering
is deterministic on the client. Cheap to store, fast to sync, portable.
4. Archetypes are starting points, never cages. The onboarding quiz assembles
a first profile; everything it builds can be rebuilt, mixed, or removed.
A musician-painter stacks a music module on top of a painting module.
5. The work is the centerpiece. Modules present it; galleries stage it.
Chrome stays out of the way.
6. PS2-era craft. Low-poly, flat-shaded, visible polygons — Mii charm with
Final Fantasy sincerity. Never photoreal, never sterile.

Core concepts and vocabulary

- Avatar: the user's low-poly character, built during onboarding, defined by
an AvatarDoc (skin, hair style/color, outfit colors, accessory).
- Profile: a person's page — avatar top-left, name/username, About Me, then
their modules. Defined by a ProfileDoc.
- Module: one block of a profile — photos, music, moodboard, text. Typed,
orderable, addable/removable at will.
- Archetype: the module set the onboarding quiz assembles from a person's
crafts (musician, visual artist, photographer, writer, ...).
- Room: the walkable 3D rendering of a module — framed works on walls, the
visitor's avatar in third person.
- Lobby (future): a shared room where multiple avatars hang out — groups,
forums, co-browsing.

Architecture

Client (now)

- TypeScript, React, Vite; three.js via react-three-fiber, drei, zustand
- Local-first v0: ProfileDoc persists to localStorage; no accounts yet
- Avatars and rooms are built from primitives at runtime — no modeled
assets, no GLTF pipeline yet; parameters in, geometry out
- Performance budget: 60 frames per second on a mid-range laptop, room
scenes under 150 draw calls, profile page interactive in under 2 seconds

Backend (next, deliberately deferred)

- Likely Supabase (auth, Postgres, storage for images/audio) once the
local-first experience is proven; profiles publish at /@username
- Forums and presence come after profiles work: apps/presence already
sketches the ephemeral co-browsing contract (never persist location)

Repo layout (pnpm workspaces)

```
apps/
web/ # Vite + React + react-three-fiber client
presence/ # WebSocket presence server (future lobbies; stub)
packages/
core/ # pure TypeScript: ProfileDoc/AvatarDoc types, archetype
# logic, seeded PRNG, color utils. No three.js, no DOM.
avatar/ # react-three-fiber low-poly avatar built from AvatarDoc
ui/ # shared 2D UI components
docs/ # design docs and architecture decision records (ADRs)
```

Conventions

- TypeScript strict mode everywhere. No `any` without an explanatory comment.
- Prettier and ESLint, enforced in continuous integration (CI).
- Conventional Commits: `feat:`, `fix:`, `chore:`, `refactor:`, `docs:`.
- Small pull requests (PRs), one reviewer minimum, no direct pushes to `main`.
- `packages/core` stays pure and deterministic: no `Math.random`, no clocks,
no three.js, no DOM (enforced by ESLint). Seeded PRNG only, so a username
can deterministically seed a default avatar.
- Every new dependency gets a one-line justification in the PR description.

Team workflow (GitHub CLI)

```bash
gh repo create <org>/<name> --private --clone
gh issue create -t "P1: avatar builder" -b "acceptance criteria..."
git switch -c feat/12-avatar-hair # branch names reference issue numbers
gh pr create --fill
gh pr merge --squash
```

- Trunk-based development: short-lived branches off `main`, squash merges.
- Every task starts as an issue; PRs close issues via `Closes #N`.
- Tag releases `v0.x`; generate changelogs from commit history.

Roadmap

- P0 Pivot: this restructure — core/avatar packages, docs honored
- P1 A person: onboarding quiz + avatar-builder tutorial, profile page with
editable modules (photos, music, moodboard, text), local persistence
- P2 A room: image modules walkable in third person — frames, captions,
soft light, the vert-menthe feeling
- P3 Real accounts: backend, publish profiles at /@username, uploads in
object storage, shareable links
- P4 Visiting: browse other people's profiles and rooms, follows, guestbook
- P5 Together: presence server lights up — avatars co-browse rooms, join
groups and lobbies
- P6 Forums: communities with threads, avatar-native, moderation tools

Working agreement for Codex

- Read this file at the start of every session.
- Prefer small, reviewable diffs. Never commit directly to `main`.
- Run `pnpm typecheck && pnpm lint && pnpm test` before proposing any commit.
- Ask before adding dependencies or changing document schemas.
- Keep `packages/core` free of side effects and nondeterminism.
- When product direction is ambiguous, re-read Product principles and pick
the warmer, more personal option.
- Codex docs, if needed: https://docs.Codex.com/en/docs/Codex/overview

Naming

Working title Atrium: the room of a house you walk into first, open to the
sky. Not user-confirmed — candidates welcome: Foyer, Vitrine, Parlor,
Alcove, Studiolo, Maquette. Verify trademark and domain availability before
any public launch. (Repo folder still says OurSpace; renaming the directory
is disruptive mid-session and cosmetic — do it whenever convenient.)
155 changes: 122 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,51 +1,140 @@
# Atrium (working title)
# ourspace

_Make yourself at home._
A portfolio-first social platform for artists and creators. People build a
low-poly avatar, assemble a personal page from creative modules, and step into
walkable galleries and music rooms. Discovery happens by visiting people and
their worlds—not by scrolling an engagement feed.

A portfolio-first social platform for artists and creators. Build a low-poly
avatar, answer a few questions about what you make, and get a warm personal
page of modules — your photography, your music, your moodboard. Image modules
open into small 3D rooms you can walk through in third person, like a private
gallery of your own work.
The current build is a local-first prototype. Profiles are stored in the
browser, so no database, account service, API key, or `.env` file is required.

LinkedIn × Instagram energy, forum features later, liminality removed on
purpose. PS2-era aesthetics: visible polygons, flat shading, Mii charm.
## What works now

## Status
- Six-step account questionnaire and PS1/PS2-inspired avatar builder
- Editable profile modules for artwork, music, moodboards, and text
- Favorite song and playlist support
- Third-person gallery rooms and creator-DJ rave rooms
- A continuous flight into a planet-style creator discovery hub
- Friends, similar, opposite, random, and new-person discovery filters
- Responsive desktop and mobile layouts

**P1 — A person.** Onboarding quiz + avatar builder, editable profile
modules, and the first walkable gallery room. Local-first: everything
persists in your browser. See the [roadmap](CLAUDE.md#roadmap).
## Run it locally

## Quickstart
### 1. Install the prerequisites

- [Node.js](https://nodejs.org/) 20 or newer
- pnpm 9.15.9

If pnpm is not installed, run:

```bash
npm install --global pnpm@9.15.9
```

### 2. Clone and start the project

```bash
git clone https://github.com/madirewolf/ourspace.git
cd ourspace
pnpm install
pnpm dev # opens the web client at http://localhost:5173
pnpm dev
```

Open the local URL printed in the terminal. It will normally be:

```text
http://localhost:5173/
```

## Repository layout
If port 5173 is already occupied, Vite prints a different port. Use the URL it
prints instead.

### 3. Create a profile

Choose **Create your space** and complete the questionnaire. The generated
profile is saved to that browser's local storage. It is safe to refresh, but it
will not automatically appear in another browser or on another computer.

For a pre-filled development profile, open:

```text
http://localhost:5173/?demo=1
```

Demo mode is temporary and does not overwrite the profile saved in the browser.

## Useful commands

Run these from the repository root:

| Path | What it is |
| ----------------- | -------------------------------------------------------------------- |
| `apps/web` | Vite + React + react-three-fiber client |
| `apps/presence` | WebSocket presence server (future avatar lobbies; stub) |
| `packages/core` | Pure TS: ProfileDoc/AvatarDoc types, archetypes, seeded PRNG, no DOM |
| `packages/avatar` | Low-poly react-three-fiber avatar built from AvatarDoc parameters |
| `packages/ui` | Shared 2D UI components |
| `docs/` | Design docs and architecture decision records |
```bash
pnpm dev # start the Vite development server
pnpm typecheck # run strict TypeScript checks in every workspace
pnpm lint # run ESLint
pnpm format:check # check Prettier formatting
pnpm test # run the Vitest suite
pnpm build # create a production build
```

## Commands
Before sharing a branch or pull request, run:

```bash
pnpm dev # run the web client
pnpm typecheck # strict TypeScript, all workspaces
pnpm lint # ESLint (core has extra purity rules)
pnpm test # vitest
pnpm build # production build
pnpm typecheck
pnpm lint
pnpm test
pnpm build
```

## Contributing
## Project structure

| Path | Purpose |
| ----------------- | ------------------------------------------------------------ |
| `apps/web` | React, Vite, and react-three-fiber client |
| `apps/presence` | Stub for future multiplayer presence and lobbies |
| `packages/core` | Pure TypeScript profile/avatar documents and archetype logic |
| `packages/avatar` | Runtime-generated low-poly avatar renderer |
| `packages/ui` | Shared interface components |
| `docs` | Architecture decisions and product notes |

## How the prototype stores data

- Profiles currently live in browser `localStorage`.
- Uploaded audio uses session-only browser URLs and may need to be re-added
after reopening the browser.
- The discoverable creator catalog is seeded prototype data.
- There is no production authentication or remote database yet.

The planned backend phase will replace these local-only pieces with real
accounts, storage, and published profile URLs.

## Working on the project

Read [AGENTS.md](AGENTS.md) for the product principles and engineering
conventions before making larger changes. In particular:

- Keep the product profile-first, never feed-first.
- Keep `packages/core` deterministic and free of browser or Three.js code.
- Use short-lived branches and Conventional Commit messages.
- Do not add dependencies without documenting why they are needed.

## Troubleshooting

**`pnpm` is not recognized**

Install the pinned version with `npm install --global pnpm@9.15.9`, close and
reopen the terminal, then run `pnpm install` again.

**The page is blank or the 3D scene is very slow**

Use a current version of Chrome, Edge, Firefox, or Safari and make sure hardware
acceleration/WebGL is enabled.

**The wrong project opens on localhost**

Check the URL printed by `pnpm dev`. Another project may already be using port
5173, in which case ourspace will start on the next available port.

**A clean profile is needed for testing**

Read [CLAUDE.md](CLAUDE.md) first — product principles are non-negotiable.
Trunk-based development, Conventional Commits, every dependency justified.
Use a private/incognito window or clear this site's local storage in the
browser's developer tools.
2 changes: 1 addition & 1 deletion apps/presence/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@atrium/presence",
"name": "@ourspace/presence",
"version": "0.1.0",
"private": true,
"type": "module",
Expand Down
9 changes: 7 additions & 2 deletions apps/web/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,13 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="color-scheme" content="light" />
<title>Atrium</title>
<meta name="color-scheme" content="dark" />
<meta name="theme-color" content="#050509" />
<meta
name="description"
content="ourspace — portfolio-first profiles and walkable creative worlds."
/>
<title>ourspace — make your corner of the internet</title>
</head>
<body>
<div id="root"></div>
Expand Down
6 changes: 3 additions & 3 deletions apps/web/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "@atrium/web",
"name": "@ourspace/web",
"version": "0.1.0",
"private": true,
"type": "module",
Expand All @@ -10,8 +10,8 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@atrium/avatar": "workspace:*",
"@atrium/core": "workspace:*",
"@ourspace/avatar": "workspace:*",
"@ourspace/core": "workspace:*",
"@react-three/drei": "^10.7.7",
"@react-three/fiber": "^9.6.1",
"react": "^19.2.7",
Expand Down
Loading
Loading