# Pocket Observatory

An original portfolio instrument for the fictional creative technologist **Avery Vale**. Ceramic-white housing, dark glass, a copper rotary control, and a constellation of three original concept projects.

This is an **original pilot inspired by public examples**, not a reconstruction of anyone’s private prompt. All identity and project content is fictional. The graphics are illustrative; their appearance does not validate astronomy, ocean science, or mechanical physics.

## Run locally

Requires Node.js 20 or newer. The application has **zero package dependencies**. No install, account, API key, or network service is required.

```sh
cd project
npm run dev
```

Open **http://127.0.0.1:4317**. If already inside the `project` folder, omit `cd project`.

`npm run dev` builds and serves the files. After editing, run `npm run build` in a second terminal and refresh the browser; this simple server does not provide hot reload. Stop with Ctrl+C.

If port 4317 is in use:

```sh
PORT=4318 npm run dev
```

The server binds to localhost only. Double-clicking `index.html` is not the supported opening method because browsers restrict JavaScript modules over `file://`.

## Use the instrument

- **Dial:** Drag around its rim to select Work, About, or Contact. It has three stops, with a bounded 240° travel. The constellation shifts while the chosen project remains highlighted.
- **Keyboard:** Tab to the dial. Left/Down and Right/Up change selection; Home and End reach the first and last section. Enter or Space opens it. Arrow keys elsewhere retain normal page behavior.
- **NEXT / OPEN:** NEXT selects the following section; OPEN displays it and moves focus to its heading.
- **Direct navigation:** Click or tap Work, About, or Contact on the screen to open it immediately. Pick projects with the numbered buttons in Work or the three stars.
- **State:** The underline indicates the dial’s selected section. The small dot marks the open section. The `TUNED TO` label states the selection. Selecting a section does not discard the project you were reading.
- **Plain text:** Follow the header link. `text.html` contains the complete portfolio and works without JavaScript.

No contact form, mail action, analytics, storage, cookies, external font requests, or external asset requests are included.

## Edit the portfolio

**All portfolio content lives in `src/portfolio.mjs`.** Change the identity, introduction, three projects, About paragraphs and principles, fictional contact address, or UI labels there. Rebuild after editing.

Keep the three section IDs (`work`, `about`, `contact`) and exactly three projects. Each project can use an existing original diagram style: `marine`, `type`, or `mechanical`. Change its `diagram` labels as needed. Custom diagram geometry lives in `src/app.mjs`; the site palette and responsive instrument live in `src/styles.css`.

For a concrete remix, `examples/portfolio-remix.mjs` supplies a complete fictional **Morgan Reed / Field Cabinet** portfolio with three replacement projects. Try it in a copy of this project:

```sh
cp src/portfolio.mjs src/portfolio.original.mjs
cp examples/portfolio-remix.mjs src/portfolio.mjs
npm run build
```

Refresh the browser. To restore, copy `src/portfolio.original.mjs` back over `src/portfolio.mjs` and rebuild. Keep real contact details out of this fictional pilot unless you deliberately adapt it for real use.

## Build and editable files

```sh
npm run check
npm run build
npm start
```

The complete static website is in **`dist/`**. The build also generates the no-JavaScript text view from the same content file. Nothing is deployed by these commands.

| File | Purpose |
| --- | --- |
| `src/portfolio.mjs` | Single editable content source |
| `src/app.mjs` | Rendering, accessible controls, original SVG diagrams |
| `src/styles.css` | Theme, physical controls, phone layout, reduced motion |
| `src/index.html` | Document shell and no-JavaScript entry point |
| `public/favicon.svg` | Original geometric mark |
| `scripts/build.mjs` | Dependency-free static build and text view generation |
| `scripts/serve.mjs` | Localhost-only server |
| `scripts/verify.mjs` | Reproducible browser checks and screenshots |
| `scripts/capture-demo.mjs` | Live browser demonstration recording |

## Recreate screenshots and demonstration

The delivered exports are actual Chromium screenshots and a browser video, not mockups. The app needs only Node; capture scripts additionally need an **existing Playwright installation and compatible Chromium**. They do not download either.

With Playwright resolvable in your environment and the site running:

```sh
CAPTURE_DIR=../exports node scripts/verify.mjs
CAPTURE_DIR=../exports node scripts/capture-demo.mjs
```

If Playwright or Chromium is installed outside standard locations, point to it explicitly:

```sh
PLAYWRIGHT_MODULE=/absolute/path/to/playwright/index.mjs \
CHROMIUM_EXECUTABLE=/absolute/path/to/chrome-headless-shell \
CAPTURE_DIR=../exports \
node scripts/verify.mjs
```

Use the same environment for `scripts/capture-demo.mjs`. Set `PREVIEW_URL` if using a different localhost port. Recording produces a silent WebM with a small pointer marker injected only into the capture session. It does not change the site’s source.

With FFmpeg already installed, create the portable MP4:

```sh
ffmpeg -i ../exports/pocket-observatory-demo.webm \
  -c:v libx264 -crf 20 -preset medium -pix_fmt yuv420p \
  -movflags +faststart -an ../exports/pocket-observatory-demo.mp4
```

These commands replace screenshot names in the chosen capture directory. Use a fresh `CAPTURE_DIR` to preserve the delivered first candidate.

## Validation and limits

Verified in installed Chromium with real desktop rendering and phone touch emulation: all sections/projects, pointer and keyboard dial operation, visible focus, NEXT/OPEN, drag seam and outside release, 390×844 phone layout, 320/768/1024 overflow, reduced motion, and complete static text-view parity with JavaScript disabled. The 200% check uses equivalent layout width/DPR, not a native browser toolbar or text-only enlargement test.

See `../exports/verification.json` for actual measured results. Physical phones, Safari, Firefox, and a human screen-reader session were not tested. Very small housing inscriptions are ornamental; the portfolio content and direct navigation remain readable. This is a portfolio demonstration, not three finished project applications.

See `../RUN.md` for runtime versions, timing, interventions, and the initial verification defects resolved before delivery. See `../ATTRIBUTION.md` for input and asset origins.
