# M-20261030-002 · S2-landing: the first screen she sees

*Private prototypes. No price anywhere. Nothing has been sent. Read-only on repos and production. Times are in America/Chicago (CT).*

**Run:** `python3 serve.py` (it binds to 127.0.0.1:18797, because 8790 belongs to the box's egress tunnel). Then open `http://127.0.0.1:18797/` to get the review hub.
**Concepts:** `a.html`, `b.html` and `c.html`. Add `?pro=julee` or `?pro=arcane` to choose the pro, plus any of these variants:
- `&device=new` simulates a forwarded link or a new device. The demo key is `K7Q2MX`.
- `&motion=reduce` shows the reduced-motion version.
- `&net=slow` shows the slow-network version.
- `&qa=1` holds navigation, for captures.

**Baseline we're beating:** `proto/_capture/julee-01-lock.png`. It asks her to type before she sees anything, the background blur is unreadable, and none of her work is visible.

## Settled decisions (CONTROL steer, 2026-10-30, 1:10 AM CT), applied in all three concepts
1. **A live Book button is the "proof it's real" beat.** "Book with Julee" / "Book a Séance" opens her real GlossGenius page in a new tab. Under it sits a chip: "● This already opens your GlossGenius". Her own page handles any deposits. We never book on her behalf. Book appears at 3 touchpoints: the header "Book", the hero button and the full site.
2. **No price** on the landing or any screen before checkout. Grep-verified: no `$`, "price" or "deposit" in any landing file.
3. **The link token only opens the preview.** It opens unlocked from the link wherever possible. The key is a fallback that is asked for **only** on "Open my site", and only on an unbound device. Claiming needs a **separate** one-time code sent to the contact on her own booking page (spec step 6). The landing never asks for a code to *see* her work.
4. The copy says **"Private preview, not public."** It never says "Only you can see this".
5. **Instagram in-app first.**
   - The layout is tested at **390×664** as well as 360×780, 390×844 and 430×932.
   - Video is muted, inline and autoplays from JS.
   - Nothing depends on hover.
   - A short-viewport CSS mode (`max-height:760px`) hides the eyebrow, scales the name by `vh`, and compacts the sheet and peek cards.
6. **No link expiry** on any screen: no countdowns, "limited" language or deadlines.

---

## The three concepts

All three share the same hero end state, so the choice is about the **first 3 seconds**, not a different product. That end state:
- her real hero clip and her name in her own type;
- one of her verbatim captions;
- the live Book button and its proof chip;
- a bottom sheet with 3 peek cards (one moment of her work with a "Book this look/ritual" CTA, her menu shown as the count only — a large "22" / "6" with "All 22 services" / "All 6 services", never a clipped service name — and one more moment), "A private preview / Made for {first}." and her true post count;
- the 56px "Open my site" button;
- the quiet links "Not me?" · "Not for me".

### A · "Already playing" (CONTROL's position, built)
- **First 2 seconds, Julee:** at 0.3 s her own brow-mapping clip is visible under a 55% ink dim. A single thread draws across the screen and **JULEE** rises while **MARIE** drops in on either side of it, the way her site works. By 1.8 s the dim lifts and the clip plays. Her name and the clip are both fully readable within 2 s.
- **First 2 seconds, Arcane:** four of her own Do-Not-Disturb lines ("No calls." / "No texts." / "No work emails." / "No news headlines.", IG Dd2MvhTTbri) sit over her dimmed treatment room and swipe away one by one. The room then irises open from the lamp, and "Custom Skin **Séance**" sets in her type.
- **Choreography, Julee:**
  - thread 150→1650 ms: draws across (to 900), holds while the words part from it, then pulls away to the right and fades. **At rest it is fully withdrawn**, so no line ever sits on the letterforms (fix1);
  - JULEE 430→1250 and MARIE 520→1340 ms, `cubic-bezier(.2,.8,.2,1)`;
  - dim lifts 1100→1800;
  - line 1300→1780;
  - header 1420; Book 1520→2000;
  - sheet rises 1850→2470 (620 ms);
  - proof chip 2370→2730.
  - Measured `reveal_completed` is about 2.8–3.1 s.
- **Choreography, Arcane:**
  - slips at 200 + i·130 ms (380 ms each, ease-in, off to the right);
  - iris `circle(0→150%)` 640→1590 ms, `cubic-bezier(.65,0,.35,1)`;
  - "Custom Skin" at 1150; "Séance" blur-in at 1400 (900 ms);
  - Book 2070; sheet 2400→3020.
  - Measured about 3.6 s.
- **Skip:** shown from 0.35 s at the top right. It hands that corner back to the header at 1.25 s (Julee) or 1.8 s (Arcane). Skip finishes every animation instantly.
- **Copy:** h2 "Made for Julee." / "Made for Alaina."; "You're one of the first pros we've invited. From 9 of your posts and your GlossGenius menu. Private preview, not public. Nothing is live."
- **Token:** opens unlocked. On an unbound device the same teaser shows and the key is asked for on "Open my site" (see Token model).
- **Reduced motion:** the end state appears immediately. The video stays paused on its poster with a 44px play/pause button. There is no slip, iris or thread animation, and no thread at all (fix1: it was a stray rule through the name).
- **Slow network:** the poster `<img elementtiming="her-work" fetchpriority=high>` is preloaded from `<head>`. The video `src` is attached by JS only after the reveal starts, as AV1 (232 KB) where supported and H.264 otherwise (Julee 337 KB, Arcane 171 KB). It is skipped entirely on Save-Data or 2g/3g, or with `?net=slow`.

### B · "In your hand" (phone mockup + one tap)
- **First 2 seconds:** her palette as a field, with "A PRIVATE PREVIEW FOR JULEE MARIE / *I built you something.*" above a phone. Her site is **already running inside the phone**: real DOM scaled down, not a screenshot, with the clip playing and her name setting.
- **Choreography:**
  - device rises 60→760 ms;
  - bottom block 500→1020;
  - inner hero sets (×0.6 speed);
  - at 3.2 s the phone scrolls itself once to her real menu ("22 services", the first 3 rows) and returns, over 4.4 s with `cubic-bezier(.45,0,.25,1)`.
  - **Open** is a shared-element expand: the screen grows to full-bleed and the scale goes s→1 over 640 ms with `cubic-bezier(.32,.72,0,1)`. The bezel and copy fade in 200–260 ms, then the page navigates to her site 140 ms later.
  - Measured settle is about 1.8 s.
- **Copy:** "Open my site"; the madeFrom line; "Your Book button already works ↗" (live); "Not me?" · "Not for me". The phone itself is also a 44px+ tap target, labelled "Open Julee's site".
- **Reduced motion:** no rise, no auto-scroll; a crossfade on open.
- **Slow network:** same poster-first rule.
- **Honest weakness:** her work is small, about 55% of the screen width. At 390×664 the phone shrinks further. "I built you something." is our voice, not hers. It reads as *a pitch about a website* rather than *her work*.

### C · "Your work, rearranged" (wildcard)
- **First 2 seconds (fix1):** a plain 3-column grid of **six pieces of her own work**, one per type (see Truth), with no Instagram UI, logos or chrome imitation. The tiles are sized to fill the screen (height = clamp(1.25×, fill, 1.9× tile width)) and the name + grid + caption are centred vertically as one group, so there is no empty band. Above it is a small mono "JULEE MARIE" and below it "*Your work.*" The layout is data-driven: if a pro has 7 or 8 tiles, the caption takes the spare cells in the last row instead of its own band. At 1.0 s the tiles lift (scale .93, radius 2→10, soft shadow) and the caption turns to "*Your website.*" At 1.25 s they re-flow: one tile becomes her full-bleed hero, two land exactly in the peek cards, and the rest fold into the hero and fade.
- **Choreography** (from the moment the tiles are decoded, or after a 1.4 s timeout):
  - tiles fade in at i·32 ms (300 ms each);
  - name at 150; caption at 520;
  - lift at 1000 (300 ms, `cubic-bezier(.2,.8,.2,1)`), caption swap at 1020;
  - re-flow 1250→2170 (920 ms, `cubic-bezier(.7,0,.2,1)`); peek tiles +60 ms; the others shrink to the hero centre over 760 ms, staggered 18 ms by distance;
  - sheet rises 1510→2150;
  - handoff at 2170: backdrop and grid fade out over 260 ms and her live hero is underneath. The name, thread, line, header and Book set at ×0.6 speed.
  - Measured `reveal_completed` is about 4.2 s. Book is visible at about 3.1 s; the header Book at about 3.0 s.
- **Truth:** the hero tile is cut from the hero poster, so the re-flow lands on the exact frame. The grid caption **claims no number**, because tiles ≠ posts (see Truth). The count appears only in the sheet: "From 9 of your posts…"
- **Reduced motion:** the A end state with the h2 "Your work, rearranged." The middle peek card becomes a 3×2 micro-mosaic of the same six tiles ("Your work · 9 posts"), so the idea survives without motion.
- **Slow network:** the tiles (about 20–35 KB each) are preloaded. Her hero poster paints underneath an opaque backdrop from the first frame, so LCP stays honest. The video follows the same rule as A.

### Side-by-side (390×844 unless noted; measured with Playwright Chromium; CPU ×4)

| | A · Already playing | B · In your hand | C · Your work, rearranged |
|---|---|---|---|
| What she sees at 0.5 s | her clip (dimmed) + thread / her slips over her room | a phone with her site in it | **6 pieces of her own work, filling the screen** |
| "This is mine" moment | her name in her type over her work | her site, small, in a device | recognising her own posts, then watching them *become* a site |
| First frame of her work, 4G (9 Mbps/85 ms) | 376 / 381 ms | 399 / 387 ms | 400 / 409 ms |
| First frame of her work, slow 4G (1.6 Mbps/150 ms) | 853 / 954 ms | 851 / 1033 ms | 1072 / 1178 ms |
| LCP, slow 4G (target < 2.0 s) | 848 / 952 ms ✓ | 852 / 1028 ms ✓ | 1064 / 1164 ms ✓ |
| Reveal settled, 4G | 3.1 / 3.6 s | 1.8 / 1.8 s | 4.2 / 4.2 s |
| Book visible | ~2.0 / 2.6 s | phone only (proof link at 1.0 s) | ~3.1 s |
| Transfer incl. video | 470 / 319 KB | 452 / 309 KB | 518 / 404 KB |
| Video (target < 400 KB) | 227 (AV1) / 167 KB ✓ | same | same |
| At 390×664 (IG in-app) | strong | weakest: the phone gets small | strong |
| Risk | looks like "a nice website" (expected) | reads as a pitch; our voice | longest; grid could read as IG (mitigated: no chrome) |
| Build cost to production | lowest | medium | medium: needs the tiles chosen per pro |

Cells with two values are Julee / Arcane. Raw numbers are in `_capture/perf.json`.

## The pick: **C, with A as its control**

1. **C is the only concept whose first frame is unmistakably hers.** Six pieces of her own work, one per kind of thing she does, are recognisable in under half a second, before any copy. A clip can be anyone's; her grid can only be hers.
2. **The motion *is* the pitch, with no words needed.** "Your work." → "Your website." as her posts fold into a real hero, menu and Book button. It shows what we did instead of claiming it. The page then lands on exactly A's end state, so nothing downstream changes.
3. **The costs are known and bounded.** It is about 1.1 s slower to settle than A (Book is at about 3.1 s), so it ships with Skip, a reduced-motion mosaic, and an A-vs-C test. If C doesn't beat A on *engaged* and *opened full site*, A wins by default because it's simpler. B is retired as a landing; its "site inside a phone" is a good candidate for the OG link-preview card (idea, not built).

## What we measure: land → continue

Events use the existing beacon surface. No typed values are sent; the payload carries `dgvid`, `slug`, `link_id`, `channel`, `concept_variant` (A/C), `device_class`, plus `rm` / `slow` / `bound`. In the prototype the names are logged to `window.__ev` and posted to `/ev` on localhost. Mapping to the SPEC names:

| Funnel step | Prototype event | SPEC event |
|---|---|---|
| landed | `landed` | `claim_link_opened` |
| first frame of her work painted | `work_first_frame {ms, via: element-timing|decode}` | new: `work_first_frame` |
| reveal | `reveal_started` / `reveal_completed {ms, skipped}` / `reveal_skipped` | `reveal_started/completed` |
| engaged | `engaged {how: tap|scroll|play3s}` (first only) | new: `engaged` |
| bounce < 5 s | `bounce_lt_5s` (pagehide/hidden before 5 s with no engagement) | new |
| peek tapped | `peek_tap {i}` | new |
| opened full site | `open_site {from: open_button|peek|device|key}` | `unlocked` + `site_opened` |
| tapped her Book button | `book_tap {touchpoint: header|hero|proof|site}` | `book_tap` |
| key fallback | `key_shown` / `key_attempted {n}` / `key_ok` / `key_bad {n}` | `lock_viewed` / `unlock_attempted` / `unlocked` |
| "make it yours" started | (on the full site) | `claim_started` (pre-step) |
| claim started | (step 6 OTP request) | `claim_started` |
| Not me / Not for me | `not_me_opened`, `wrong_person`, `not_for_me_opened`, `not_for_me {reason_code}` | `wrong_person` / `not_for_me` |

**Metrics**
- **Time to first frame of her work (TTFF):** p50 and p90 by `channel` and `device_class`. Target p90 < 1.5 s. This is the number that matters most; the page is judged in the first second.
- **Bounce < 5 s:** share of `landed` with `bounce_lt_5s`.
- **Land → engaged → opened full site → Book tap / make-it-yours → claim started:** per link, not per session.
- **Forwarded-link opens:** a `landed` on a **second `dgvid`** for the same `link_id`, plus `key_shown` from unbound devices. We report this as a count and ratio, because a forward is good news (she showed someone). It is never a failure, and it never unlocks claim.
- **Skip rate** (C/A): if skips are above about 30%, the reveal is too long.
- **Not me / Not for me rates and reasons:** these are a stop signal for a pro, not a metric to optimise.

**A/B plan.** Assign A or C per **link**, never per session, so forwards and returns see the same thing; record `concept_variant`. Alternate assignment within each send batch, stratified by channel (IG DM vs SMS). **Cohorts will be small (dozens of pros, not thousands), so early numbers are read qualitatively.** Watch session replays and replies alongside the funnel. Don't call a winner from a few percentage points. Switch only on a large, consistent gap (for example opened-full-site ≥ 2× over 30+ links per arm) or on clear qualitative signal ("I watched it three times").

## Token model (my position vs CONTROL's)

I agree with CONTROL's starting point: the token unlocks without typing and the key is only a fallback. I changed *where* the fallback appears.

- **The teaser is safe for anyone.** It holds only her faceless public work, her name, her public menu and her public booking link. So the landing never locks; a forwarded link still shows the teaser.
- **Binding:** the first genuine JS open binds the device (cookie, 30 days, server-side). Link-preview bots don't run JS, so they don't bind.
- **The key is asked for only on "Open my site", and only on an unbound device:**
  - copy: "This was made for Julee. Enter the 6-character key from Tony's message to open it on this device.";
  - `autocomplete="one-time-code"`, auto-submit on paste;
  - 5 tries, then "Reply to Tony's message and he'll send a fresh link.";
  - "Not me?" is available on the sheet.
- **The key never goes in the URL**, because a prefilled link would defeat forwarding protection. For SMS, end the message with an origin-bound line (`@styled.page #K7Q2MX`) so iOS and Android offer it in one tap.
- **Instagram:** the IG in-app browser and Safari count as different devices. That's acceptable, because she has the key in the DM.
- **Claim is separate:** a one-time code goes to the contact on her own booking page (step 6). A forward can never reach checkout.

## Accessibility and QA (fix1 re-run, ~2:05–2:20 AM CT: 3 concepts × 2 pros × 360×780 / 390×844 / 430×932 / 390×664, each also in reduced motion = 48 runs)
- **Tap targets:**
  - all visible `a`, `button` and `input` elements are ≥ 44×44 (0 failures);
  - "Open my site" is 56 px (52 px in short mode);
  - "Book with Julee" / "Book a Séance" is 52 px;
  - the header Book is 44 px;
  - the quiet links are 44 px tall.
- No horizontal overflow (0). Minimum visible font size is 12 px (0 failures). No console errors (0).
- **Contrast** method (fix1): hide the text, screenshot its box at **5 moments 750 ms apart (~3 s of video)**, then take the 1st-percentile (near-brightest) background pixel against the text colour. Buttons are inset (h/2 × 0.22h). The 3:1 large-text rule applies to the name, title and h2; the rest need 4.5:1. Eyebrow and peek-label opacity is now 1, so the measured colour is the rendered colour.
  - **Result: 0 failures of 616 text measurements.** Lowest per concept: A eyebrow 7.64 · hero line 6.53; B quiet button 5.86; C eyebrow 7.55 · hero line 6.59.
  - **Arcane eyebrow (was 3.96 rm / 4.32 at 430)**, measured on the brightest of 5 frames: C 13.43 / 10.86 / 10.49 at 360 / 390 / 430, reduced motion 12.82 / 11.74 / 11.01; A 13.10 / 12.44 / 10.39, rm 12.82 / 11.74 / 11.01. **Strict re-measure with every text-shadow switched off** (so the halo can't help): C 11.81 / 10.69 / 8.85, rm 10.32 / 9.00 / 8.46; A 11.89 / 9.84 / 8.53, rm 10.32 / 9.00 / 8.46. At 390×664 the eyebrow is hidden by design (short mode), so there is nothing to measure. Fix: top scrim extended (.94 → .62 at 16% → 0 at 32%), eyebrow #F6F0E6 at opacity 1 (was --fg at .92 after the reveal), plus a tight dark halo.
  - The old "Julee name in reduced motion 2.4–2.6" artifact is gone with the thread.
  - Caveat: 1st percentile means up to 1% of background pixels (e.g. a candle flame) can be brighter than the reported value.
  - Results: `_capture/qa-contrast.json` (`arcane_eyebrow_fix1` holds both sets).
- Also 0 tap targets < 44 px, 0 horizontal overflow, 0 fonts < 12 px, 0 console errors, 0 primary actions off-screen, across all 48 runs.
- **Stills:**
  - end states: `_capture/stills/{a,b,c}-{julee,arcane}-{WxH}[-rm].png`;
  - first frames: `first-*-500ms.png` / `first-*-1000ms.png`;
  - states: `state-key-julee.png`, `state-key-wrong-julee.png`, `state-notme-arcane.png`, `state-notforme-arcane.png`, `state-gone-arcane.png`, `state-slow-julee-390x664.png`.
- **Recordings** (390×844, about 8 s each; C and A re-recorded in fix1, B is v1, ending on the "Open my site" hand-off into her real concept site): `_capture/rec-{a,b,c}{julee,arcane}.mp4`.
- **LCP / TTFF** in `_capture/perf.json` (**not re-run in fix1**: the shared box was at load ~117, so timings would be meaningless; C now preloads 6 tiles instead of 9, so it should not be slower): CDP throttling with cache disabled, at Lighthouse slow-4G (1.6 Mbps/150 ms/CPU ×4) and 4G (9 Mbps/85 ms/CPU ×4). These are emulated, not measured on a device. In headless Chromium the IG in-app and iOS Safari behaviour is **UNVERIFIED**; it needs one real-phone pass.

## Truth and provenance
- **Every string has a source.** Each one in `data/pros.js` carries its source (content.json → GG / IG). Nothing is invented. The draft hero line "Nothing here happens by accident." was avoided in favour of her verbatim IG caption "Good brows don't happen by accident." (DbmA4PiJvTF).
- **Media:**
  - only her own work, cropped and resized only (`assets/TILES-PROVENANCE.json`, built by `_build/crops.py`);
  - nothing is AI-altered;
  - no owner face;
  - no full client faces.
- **"Made from {n}" counts** are distinct IG posts whose photo or video appears on her full concept site, verified by shortcode in the enrichment manifests:
  - **Julee 9:** DbmA4PiJvTF, Ddp_GTqtat9, De0rGI4xNFg, DaN0hd_lSNj, DfAvDp9isG_, De6-q0zkbM8, Dcw702KiTvx, DSP_IKCjRq-, DYh-rvKJEqP.
  - **Arcane 5:** DeIOT2-TYMF, Ddr5lS_PXz9, DbwH2jJoCbF, Dd2MvhTTbri, Dez-Y5lxz2B. Her site also quotes caption text from 3 more posts (DesRfyuzAqO, CrM6rxAOzLt, DfDaKSjRfKs); the copy says "your posts, your captions" without counting them.
- **C grid tiles (fix1), rule:** at most 1 tile per treatment type; finished results preferred over mid-treatment; at most 1 eye close-up; her real harvested media only, crop + resize only (3:5, 384×640, `_build/crops2.py` → `assets/TILES-PROVENANCE.json`, which records source file, crop box, post, type, stage and sha256 per tile). Nothing generated stands in for her work.
  - **Julee (6):** t-hero brow mapping (hero poster; the one eye close-up, mid-treatment) · t-neon her suite neon · t-wax waxing (mid-treatment) · t-glam makeup, lips and skin, no eyes (finished) · t-heels her brand: stilettos and sign · t-times her brand: The Julee Marie Times (cropped below her chin; no owner face).
  - **Arcane (6):** t-arch the room, apothecary arch · t-hero the room in lamplight (hero poster) · t-globes facial, gold globes in her hands · t-blade dermaplaning · t-lamp the room, lamp and candle · t-arrow result after her treatment, lips/chin only, no eyes.
  - **Tried and rejected:** Julee's lash-lift result (would be a second eye close-up); the old brow-map tiles j1/j7 (same type as the hero: this was the "3 near-identical brow tiles" problem); Julee facial result (DfAvDp9isG_), because every eye-free crop is an unreadable patch of jaw/ear; Julee facial-massage hands (De0rGI4xNFg), because the 432×540 source is motion-blurred in every frame; Arcane result-1 (same type as globes and doesn't read without the eyes) and room-steam (near-identical to the hero room). So each pro has 6 strong tiles rather than 9 padded ones.
  - Arcane's three room views are her studio, not a treatment, and are three different compositions (arch, lit table, lamp).
  - **Tiles ≠ posts:** Julee's 6 tiles come from 5 posts (t-neon and t-times are both cut from her portrait post DSP_IKCjRq-, neither showing her face); Arcane's 6 come from 4 posts (all three room views are frames of her room video Dd2MvhTTbri). So the grid makes no numeric claim.

## Tony's decisions (2026-10-30, ~1:50 AM CT, his words via CONTROL), applied in fix1
1. **Retention policy.** If she chooses "Not for me" → "Remove my preview" (or "Not me?" → "Put it away"), the link is retired and the screen says exactly: **"Your photos are deleted within 30 days."** The photos and videos gathered from her public posts are deleted within 30 days. **The design and art direction are kept, with her identity stripped** (name, handle, photos, captions, booking link, location), for the template library. We never promise to delete the design, on the landing or in outreach.
2. **Sender.** "Tony, founder and designer" (short form "Tony" where space is tight) replaces every "Anthony" in the landing and every outreach draft.
3. **Chosen and early.** Outreach tells her she was chosen and will be among the first pros to use the product. On the landing it appears once, lightly, as the first sentence of the sheet copy under "A private preview": **"You're one of the first pros we've invited."** (A and C; B carries it in its bottom line). No numbers, no countdowns, no scarcity, never "exclusive" or "only".

## Pre-outreach gate — OPEN (fix1). No outreach of any kind until every box is ticked.
- [ ] **Real phone, Instagram in-app browser** (iOS and Android): open the link from an IG DM; check first frame of her work < 1.5 s, muted inline autoplay, the grid → hero re-flow, Skip, Book opening her GlossGenius (in IG's browser and via "open in Safari/Chrome"), "Open my site", the key fallback on a second device, Not me / Not for me, and reduced motion. Viewport about 390×664.
- [ ] **Real phone, iOS Safari:** the same list, plus the SMS one-tap key line, safe-area insets, and low-power mode (autoplay off → poster + play button).
- [ ] **OG link-preview cards** built (1200×630, her work, no price, no "only you", no expiry) and checked as they actually unfurl in IG DM, iMessage and SMS. Link-preview bots must not bind the device.
- [ ] **Retention job live:** the photo deletion within 30 days actually runs (and the identity strip of the kept design) before any outreach promises it.
- Owner: Tony. Headless Chromium results in this folder do **not** count toward this gate.

## Open flags for Tony
1. **RULING (fix1) — partial-face close-ups:** these are covered by the client-face rule. They are usable **after the pro claims and attests**; until then they are **private concept only**. On this landing that means the Julee hero brow-map clip/poster (eye close-up), t-glam (lips) and Arcane t-globes / t-arrow (partial face). Nothing in this folder is public.
2. **RULING (fix1) — the live Book button is Tony's yes.** It opens her real booking page, deposits included as her page handles them; we never book for her. **Follow-up, not done here:** the dgenius-brain voice note still says "a forwarded page must not link to anything that takes money" and needs updating to match. I did **not** edit that repo (read-only rule); someone with that repo should change the note.
3. **DECIDED (Tony, fix1) — sender name:** "Tony, founder and designer"; short form "Tony" where space is tight. The landing uses the short form in the key screens ("…from Tony's message", "Reply to Tony's message…"). Outreach uses the full form; see `../S3-OUTREACH.md` (v1 kept as `S3-OUTREACH.v1.md`).
4. **DECIDED (Tony, fix1) — put-away promise:** the "Put away." screen says exactly "Your photos are deleted within 30 days." We do **not** promise to delete the design. See Retention policy. The deletion job itself is not built; it must exist before the first send (part of the pre-outreach gate).
5. **Arcane copy source:** the s3 quote on her full site has no pinned post. It isn't used on the landing.
6. **Not yet built:** OG link-preview cards (1200×630) and the real-device passes. Both are now part of the **pre-outreach gate** below.
