# hejpics — your photos, kept quietly

[![License](https://img.shields.io/github/license/nabbisen/hejpics)](LICENSE)
[![crates.io](https://img.shields.io/crates/v/hejpics?label=hejpics)](https://crates.io/crates/hejpics)
[![Rust Documentation](https://docs.rs/hejpics/badge.svg?version=latest)](https://docs.rs/hejpics)
[![Dependency Status](https://deps.rs/crate/hejpics/latest/status.svg)](https://deps.rs/crate/hejpics)

> *Photos belong to the user. Time belongs to the user.*

**hejpics** is a privacy-first photo library and sharing service.
There is no public timeline, no algorithmic feed, no advertising,
and no AI training on user photos. Sharing is always explicit — by
private link, invitation, or Family key — and always revocable.

This repository contains the **Web GUI mockup**: a navigable,
visually complete Leptos + WebAssembly implementation of the user
interface defined in the product specifications. Business logic is
mocked in-memory; this is a UI prototype, not a backend.

## Overview

The application is a single-page Progressive Web App written in
Rust, compiled to WebAssembly, and served as static assets. The
visual design is *refined editorial minimalism* — calm, warm, and
trustworthy, deliberately antithetical to social-media surfaces.

The mockup covers fifteen routes including the upload privacy flow,
album library, photo viewer, share centre, data ownership centre,
settings, and the public shared-album entry/viewer for non-account
recipients.

## Why / When

Use this codebase as the starting point for the hejpics frontend
implementation, or as a reference for:

- accessible-by-default Leptos UI patterns (keyboard, screen reader, reduced motion)
- privacy-first information architecture (no public-by-default surfaces)
- a Rust + Wasm CSR app structured with `leptos_router` 0.8

The mockup is intentionally complete in terms of *screens and
transitions*, not in terms of network calls, authentication, or
storage. Every photo, album, and share link is dummy data.

## Quick Start

### Prerequisites

- Rust **1.91** or later (via [rustup](https://rustup.rs))
- The `wasm32-unknown-unknown` target
- [cargo-leptos](https://github.com/leptos-rs/cargo-leptos)

```bash
# install Rust
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup install 1.91
rustup default 1.91

# add the wasm target
rustup target add wasm32-unknown-unknown

# install cargo-leptos
cargo install cargo-leptos
```

### Run the dev server

```bash
# run from the workspace root
cargo leptos serve
```

Open `http://127.0.0.1:3000`. cargo-leptos watches for changes and
reloads automatically.

### Build for production

```bash
cargo leptos build --release
# Server binary: target/server/release/server
# Static assets: target/site/
```

Deploy the `server` binary alongside the `target/site/` directory,
with the environment variable `LEPTOS_SITE_ROOT` pointing to the site
directory.

### Type-check without the wasm target

```bash
# SSR half (host target)
cargo check --features ssr

# Hydrate half (host target, type-check only — no wasm32 needed)
cargo check --lib --features hydrate
```

## Design Notes

- **Stack.** Rust 2024, Leptos 0.8 SSR + Hydrate, `leptos_axum 0.8`, `axum 0.8`, `leptos_router 0.8`. No nightly features.
- **Rendering.** Server renders the initial HTML via axum + `leptos_axum`; the browser hydrates it with the Wasm bundle. No CSR flash on first load.
- **Build tool.** `cargo-leptos` (replaces Trunk). Compiles the SSR binary (`ssr` feature) and the Wasm hydrate bundle (`hydrate` feature) in one command.
- **Entry points.** `src/main.rs` — axum server (SSR feature). `src/lib.rs` — `#[wasm_bindgen(start)]` hydrate entry (wasm32 target). `src/app.rs` — `shell()` generates the outer HTML document including `<HydrationScripts>` and `<HashedStylesheet>`.
- **State.** `AppState` via Leptos context with reactive signals. Mock data is deterministic so there are no SSR/hydrate mismatches.
- **Browser-only code.** `web_sys` / `wasm-bindgen` types compile on all targets as stubs. Only `state.rs`'s `Closure::once_into_js` + `setTimeout` is guarded with `#[cfg(target_arch = "wasm32")]`.
- **Visual system.** Warm parchment palette (`#FAF7F2` paper, `#1A1814` ink), sage accent (`#6F8A6A`) for trust-affirming actions, coral (`#B85540`) for destructive. Typography: **Fraunces** + **IBM Plex Sans** + **IBM Plex Mono**.
- **Accessibility.** WCAG 2.2 AA. All primary actions keyboard-reachable. Touch targets ≥44px. High-contrast, reduced-motion, large-text toggles wired live through Settings.
- **Privacy IA.** No screen offers global public sharing. No button reads "Publish". Every shared state is explicit and revocable in one tap.

## Project structure

```
hejpics/
  Cargo.toml            # workspace (resolver=3, edition 2024, rust 1.91)
  crates/
    hejpics-web/        # the Leptos web crate
      Cargo.toml
      leptos.toml       # cargo-leptos build config (at workspace root)
      styles/main.css   # full design system (~1700 lines)
      src/
        main.rs         # SSR entry (axum server, ssr feature)
        lib.rs          # module declarations
        app.rs          # router + route tree
        state.rs        # AppState, reactive signals
        i18n.rs         # static EN/JA translation table
        mock.rs         # seed albums + photos
        components.rs   # component module declarations
        components/
          app_shell.rs       # trust header + bottom nav scaffold
          trust_header.rs    # brand, privacy badge, lang switch
          bottom_nav.rs      # primary navigation
          toast.rs           # transient feedback stack
          confirm.rs         # destructive action dialog
          icons.rs           # inline SVG icon set
        pages.rs        # page module declarations
        pages/
          home.rs / albums.rs / album_detail.rs
          photo_viewer.rs
          upload_start.rs / upload_privacy.rs
          upload_processing.rs / upload_complete.rs
          share_center.rs / create_share_link.rs
          create_album.rs
          data_center.rs / settings.rs
          shared_entry.rs / shared_viewer.rs
  rfcs/                 # design RFCs (see 000-rfc-lifecycle-policy)
  docs/                 # full documentation (mdbook-compatible)
```

## More

- **Full documentation:** see [`docs/src/`](./docs/src/) (mdbook-compatible).
- **RFC lifecycle:** see [`rfcs/done/000-rfc-lifecycle-policy.md`](./rfcs/done/000-rfc-lifecycle-policy.md).
- **License:** Apache-2.0 — see [`LICENSE`](./LICENSE) and [`NOTICE`](./NOTICE).
- **Author:** [nabbisen](https://github.com/nabbisen).
