# handoff.joypixels.com

The EmojiCopy **Handoff Workspace** — design mockups and dev handoffs for the EmojiCopy app, plus outbound marketing drafts. Plain static HTML/CSS/JS: no build step, no server code.

- **Live**: `handoff.joypixels.com` — dev-hosted, served from this repo on push.
- **Sign-in**: the site gates itself with the same PKCE OAuth flow as the collections admin (details below).

```
.
├── index.html               ← Handoff Workspace home
├── components.html          ← Component catalog (green Components pill on every page jumps here)
├── handoff/                 ← MOCKUPS · in-app surfaces (specs the dev builds in Vue)
│   └── index.html             · category nav: Pro & pricing / Onboarding / App surfaces / Admin / Old site
├── comms/                   ← OUTBOUND (published/sent by marketing)
│   └── index.html             · category nav: Blogs / Socials / Banners / SEO / Emails
├── auth/                    ← sign-in (login + OAuth callback pages)
├── assets/                  ← shared CSS/JS: tokens, app mirrors, workspace components, auth, favicons
├── copy.md                  ← campaign copy in one file
├── PLANS-PRICING.md         ← canonical tiers/pricing/gating
├── VUE-CONVENTIONS.md       ← authoring rules for anything that lands on the dev's plate
├── DEV-NOTES.md             ← logged deviations + build flags
├── DESIGN-PRINCIPLES.md     ← house design rules
└── DEFINITIONS.md           ← workspace vocabulary
```

## The two halves

| | `handoff/` | `comms/` |
|---|---|---|
| **Purpose** | Visual spec for an in-app surface the dev builds | Outbound piece marketing publishes/sends |
| **Audience** | Dev | Blog, X, ESP |
| **Handoff code** | Complete drawer under every mockup card | Emails only — ESP-ready HTML (promo) or full HTML+CSS (account) |

If it gets **built into the app**, it goes in `handoff/`. If we **send or publish it ourselves**, it goes in `comms/`.

### Emails: promo vs account

- **Promo** — sent by marketing via SendGrid. Drawer = one ESP-ready HTML pane (table-based, inline styles).
- **Account** — sent by the app transactionally; the dev builds it. Drawer = full handoff: send-ready HTML (every style inlined; head `<style>` keeps only client resets / media queries / Outlook dark overrides) + CSS + behavior notes. Toggle reads "View full handoff".

Each email page carries its Promo/Account badge; `comms/index.html` lists the kinds separately.

## The design system — a 3-layer CSS stack

Loaded in this order on every page:

1. **`assets/tokens.css`** — design tokens, a 1:1 mirror of the EmojiCopy app's `ui/css/colors.css` + typography (`--c-surface-cta`, `--sp-4`, `--r-pill`, `.f:body/l-heavy`, `.c:white/txt`).
2. **`assets/app-components.css`** — **verbatim mirror** of the app's shipped component CSS (`ui/buttons/*.vue`, `ui/components/Text.vue`). When the app edits a scoped style, update the matching block here. Never add new components to this file.
3. **`assets/components.css`** — **proposals**: components that don't exist in the app yet (flagged 🟡 in the catalog). When the app ships one, its CSS graduates to `app-components.css` and the badge flips to ✓.

The app source is the reference, not a dependency — nothing here imports from it. When working locally with the app checkout available, it lives at `../emojicopy-client-main/` (`ui/` components, `ui/css/colors.css`, `dev-reference/notion/` for internal dev docs).

**Never invent values.** Every color, spacing, radius, and font in a mockup comes from `tokens.css`; every element reuses an app component if one exists. Genuinely new things get the 🟡 badge.

## The handoff drawer pattern

Every `handoff/` page is a stack of **mockup cards** — the cards are choices. Under each card, a "View handoff" drawer holds everything needed to build that exact card:

1. **Component badges** — ✓ reused from `ui/` · 🟡 new.
2. **Vue pane** — full component source.
3. **Invocation pane** — this card's exact props/config.
4. **CSS pane(s)** — the composition CSS plus every 🟡 atom's scoped CSS. Flat selectors only (`.thing__part`, never `&__part` nesting — browsers drop it).
5. **Behavior notes** — timing, gating, telemetry, anything not visible in the mockup.

Every drawer is **complete on its own** — repetition across cards is deliberate; the dev never hunts another card to finish a build. `handoff/feedback-flow.html` is the reference implementation.

Descriptions stay simple: page headers and index subs say what the thing is in one or two plain sentences; meta lives in drawer notes.

## Sign-in

Same OAuth client and flow as the collections admin (PKCE against `admins.emojicopy.com`, verify via `/api/account/me`). View access only — no publish/sync machinery.

- `assets/auth.js` — the whole flow; loaded on every page by `assets/chrome.js`.
- `auth/login/` + `auth/callback/` — the sign-in card and OAuth callback pages.
- Enforcement: always on real hosts; **off on localhost** unless forced with `?authgate=1` (off again with `?authgate=0`), so local work has no friction.
- Whitelisted callbacks: `https://handoff.joypixels.com/auth/callback` and `http://localhost:4401/auth/callback`.

## Current product rules (beta program)

- Founding-500 offer is **annual-only** — 50% off Pro for life, first 500, recurring. Standard offer: 50% off first year, one-time. Both codes auto-apply (`FOUNDING50` / `BETA50`).
- Free is ad-free during the beta; the emoji grid bottom carries the Pro upsell strip.
- Feedback = rating + comment only. Guest mode off during beta.
- Full detail: `PLANS-PRICING.md`.

## Working locally

```bash
python3 -m http.server 4400
# → http://localhost:4400/  (use PORT 4401 when testing sign-in — that's the whitelisted callback port)
```

## Adding a page

**Handoff page**: copy `handoff/feedback-flow.html`, build the mockup from `tokens.css` + `app-components.css` + `components.css`, give every card its complete drawer, then link it in the right category on `handoff/index.html`. New components also get a `components.html` catalog entry.

**Comms page**: copy any `comms/*.html`, use the same tokens, link it in the right category on `comms/index.html`. Email pages also load `handoff.css`/`handoff.js`, carry a Promo/Account badge, and put the right drawer under every mockup.
