# Lion and Lamp — Story Library cPanel Upload Guide

This is a **self-contained static site**. There is no server code, no database,
no build step. Drop the files into cPanel and you're live.

---

## What's in this package

```
/index.html                                ← protected library / hub page (3 story cards)
/login.html                                ← sign in / create account page
/subscribe.html                            ← subscription plan page with Stripe Payment Link placeholders
/subscribe-success.html                    ← post-payment status page
/README_UPLOAD.md                          ← this file
/.htaccess                                 ← Apache config (gzip, caching, JSON MIME)
/robots.txt
/assets/
    auth.js                                ← Supabase auth helper; paste URL + anon key here
    auth-guard.js                          ← protects library and story pages
    lion-and-lamp.css                      ← shared design tokens & base styles
    player.css                             ← shared story player styles
    player.js                              ← shared story player (loads story.json)
    noah/                                  ← optimized Noah images + short intro video
/stories/
    david-goliath/
        index.html                         ← player page
        story.json                         ← scene data
    fiery-furnace/
        index.html
        story.json
    noah/
        index.html
        story.json
```

Each story has the **exact same structure**. Adding a fourth story later is just:
copy any story folder, edit `index.html` (title, scene-icon map) and write a
new `story.json`. The player code in `/assets/player.js` is shared.

---

## Option A — Put the library at `lionandlamp.com/library` (recommended)

This is the cleanest option. Your existing landing page at `lionandlamp.com/`
stays exactly as it is. Subscribers go to `/library` after login.

### cPanel File Manager steps

1. Log in to cPanel and open **File Manager**.
2. Navigate to `public_html/`.
3. Click **+ Folder** and create a new folder named `library`.
4. Open the new `library/` folder.
5. Click **Upload** (top toolbar).
6. From your computer, select **every file and folder inside this package**
   (`index.html`, `README_UPLOAD.md`, `.htaccess`, `robots.txt`, `assets/`,
   `stories/`). You can drag the whole folder contents in.
   - Note: in File Manager you may need to upload the `.zip` and then use the
     **Extract** button on the right-click menu. That's fine too.
7. After upload, your structure should look like:

   ```
   public_html/
     library/
       index.html
       assets/
       stories/
       .htaccess
       ...
   ```

8. Visit `https://lionandlamp.com/library/login.html` in your browser. The
   sign-in page loads. If Supabase is not configured yet, it will show a setup
   note.

### One-line link your existing checkout / Supabase auth flow should send to

```
https://lionandlamp.com/library/login.html
```

No new Stripe subscription concept is needed. Use the same **Adventurer** plan
you already sell. New subscribers should go through `/library/subscribe.html`,
and active subscribers land at `/library/`.

---

## Supabase setup

### Paste your project values into `assets/auth.js`

Open this file in cPanel:

```
public_html/library/assets/auth.js
```

Near the top, replace:

```js
const SUPABASE_URL = 'YOUR_SUPABASE_URL';
const SUPABASE_ANON_KEY = 'YOUR_SUPABASE_ANON_KEY';
```

with your real Supabase values:

```js
const SUPABASE_URL = 'https://your-project-ref.supabase.co';
const SUPABASE_ANON_KEY = 'your-anon-public-key';
```

Keep the quote marks.

### Create the `subscriptions` table

In Supabase SQL Editor, run this migration:

```sql
create table if not exists public.subscriptions (
  id uuid primary key default gen_random_uuid(),
  user_id uuid references auth.users(id) on delete cascade,
  email text,
  plan text default 'adventurer',
  status text default 'pending',
  created_at timestamptz default now(),
  updated_at timestamptz default now(),
  unique(user_id)
);

alter table public.subscriptions enable row level security;

create policy "Users can read their own subscription"
on public.subscriptions
for select
to authenticated
using (auth.uid() = user_id or auth.email() = email);

create policy "Users can create their pending subscription"
on public.subscriptions
for insert
to authenticated
with check (auth.uid() = user_id);

create policy "Users can update their pending subscription"
on public.subscriptions
for update
to authenticated
using (auth.uid() = user_id)
with check (auth.uid() = user_id);
```

Your n8n Stripe webhook should update the matching row to:

```sql
status = 'active'
```

after Stripe confirms payment.

---

## Stripe setup

Open this file in cPanel:

```
public_html/library/subscribe.html
```

Replace these placeholders near the bottom:

```js
const STRIPE_PUBLISHABLE_KEY = 'YOUR_STRIPE_PUBLISHABLE_KEY';
const PAYMENT_LINK_FOUNDING = 'YOUR_PAYMENT_LINK_FOUNDING';
const PAYMENT_LINK_STANDARD = 'YOUR_PAYMENT_LINK_STANDARD';
```

Use your Stripe Payment Link URLs for the two plan buttons. The publishable key
is included as a placeholder for later, but Payment Links themselves do not need
custom JavaScript checkout code.

---

## Option B — Replace `public_html/` so the library IS the homepage

Only do this if you want `lionandlamp.com/` itself to be the library (instead
of the marketing landing page).

1. **Back up your current site first.** In File Manager, select everything in
   `public_html/`, right-click → **Compress** → save as `site-backup-YYYY-MM-DD.zip`,
   then download it.
2. In `public_html/`, delete the existing files (keep your backup zip).
3. Upload everything from this package into `public_html/` directly.
4. Visit `https://lionandlamp.com/` — the library hub loads.

**Recommended:** stick with Option A. Keep marketing and library separate.

---

## Option C — Subdomain (e.g. `app.lionandlamp.com`)

If you want a dedicated subdomain for the app:

1. In cPanel, **Subdomains** → create `app.lionandlamp.com` with document
   root `public_html/app`.
2. Upload everything from this package into `public_html/app/`.
3. Visit `https://app.lionandlamp.com/`.

---

## You do NOT need a whole new subscription model

The existing **Adventurer** ($4.99/mo standard) and **Founding Family**
($2.99/mo lifetime locked) plans **already entitle subscribers to every
story in this library — current and future**. The hub copy already says this.

The only Stripe work is creating/pasting the two Payment Links into
`subscribe.html`. You do not need a separate plan for Noah or future stories.

Recommended flow:

1. Visitor creates account at `/library/login.html`.
2. Visitor chooses a plan at `/library/subscribe.html`.
3. Stripe redirects to `/library/subscribe-success.html`.
4. n8n receives Stripe webhook and marks `subscriptions.status = 'active'`.
5. Active subscribers can read `/library/` and `/library/stories/*`.

This package now includes gate code. `assets/auth-guard.js` protects the
library home and each story page. Visitors who are not signed in go to
`/library/login.html`. Signed-in visitors without active subscriptions go to
`/library/subscribe.html`.

---

## Adding a new story later (5-minute job)

1. Duplicate any folder under `/stories/`, e.g. `stories/noah/` → `stories/jonah/`.
2. Edit the new `index.html`:
   - Change `<title>`, `<meta description>`, and the on-page brand title.
   - Update the `LionAndLamp.boot({...})` call:
     - `totalScenesEst` (rough scene count for progress bar)
     - `characters` (two options, with avatar/desc/pronoun/possessive)
     - `sceneBg` (color + emoji per scene ID)
     - `codaHtml(state)` (the "back to bed / back home" closing paragraphs)
3. Write `stories/jonah/story.json` following the same shape (see below).
4. Add a card on `/index.html` pointing to `stories/jonah/index.html`. Done.

### `story.json` shape

```json
[
  {
    "SCENE_ID": "S0",
    "TITLE": "...",
    "DESCRIPTION": "Use \\n\\n for paragraph breaks. Use [NAME] and [POSSESSIVE] / [PRONOUN] for the player's character.",
    "LEADS_TO_A": "S1",
    "LEADS_TO_B": "S1"
  },
  {
    "SCENE_ID": "S1",
    "TITLE": "...",
    "DESCRIPTION": "...",
    "CHOICE_A": "First option text",
    "LEADS_TO_A": "S2A",
    "CHOICE_B": "Second option text",
    "LEADS_TO_B": "S2B"
  },
  {
    "SCENE_ID": "S2A",
    "TITLE": "...",
    "DESCRIPTION": "...",
    "AUTO_ADVANCE": true,
    "LEADS_TO": "S3"
  },
  {
    "SCENE_ID": "END_FAITH",
    "TITLE": "...",
    "DESCRIPTION": "...",
    "END": true,
    "ENDING_BADGE": "🌟 The Faith Path",
    "SCRIPTURE": "\"...\"",
    "REFERENCE": "Book 1:1"
  }
]
```

Supported fields:

- `SCENE_ID` — must be unique. Use `S0` for the character-select scene.
- `TITLE`, `DESCRIPTION` — display text. `[NAME]`, `[PRONOUN]`, `[POSSESSIVE]` are replaced live.
- `CHOICE_A` / `LEADS_TO_A` — choice text and target scene ID (A through D supported).
- `AUTO_ADVANCE: true` + `LEADS_TO` — shows a single "Continue" button.
- `END: true` + `ENDING_BADGE` + `SCRIPTURE` + `REFERENCE` — ending screen.

### Story images and video

Noah includes real scene art in `/assets/noah/`. The player supports:

- `sceneVideo` — used on Noah's opening character-select screen. The current
  video is muted, autoplaying, looping, and compressed for mobile.
- `sceneImages` — maps scene IDs to a general image or separate `boy` / `girl`
  images. The Noah story uses boy-specific artwork for Caleb, girl-specific
  artwork for Miriam, and shared images for general ark scenes.

For future stories, add media files under `/assets/<story-name>/`, then add
`sceneVideo` and/or `sceneImages` to that story's `LionAndLamp.boot({...})`
call in `stories/<story-name>/index.html`.

---

## Browser support & limitations

- Works in any modern browser (Chrome, Firefox, Safari, Edge, mobile Safari, Chrome Android).
- **Does NOT use** browser persistence, cookies, or immersive browser APIs, so
  the build runs cleanly inside the Perplexity preview sandbox and any embedded
  iframe.
- All state (which scene you're on, which character you chose) lives only in
  memory. Refresh the page and you start over. This is intentional for the
  current build.

## Troubleshooting

**"Could not load this story" on a story page.**
The browser couldn't fetch `story.json`. Two common causes:

1. You opened the file directly from disk with `file://`. Some browsers block
   `fetch()` from `file://` URLs. Test by uploading to cPanel, or run a local
   server (see "Local smoke test" below).
2. Your server isn't sending JSON files with the right MIME type. The included
   `.htaccess` fixes this on Apache (`AddType application/json .json`). If your
   host doesn't honor `.htaccess`, ask support to enable mod_mime.

**Fonts look generic.**
The site uses Boska + General Sans from Fontshare via CDN. If your visitor's
network blocks `api.fontshare.com`, system serifs/sans take over — it still
looks fine, just less distinctive.

**Need to deploy a preview before going live?**
Zip the whole folder, drop it on a static host (Netlify drop, Vercel, Cloudflare
Pages, even GitHub Pages). Everything is relative paths — no env variables, no
config.

## Local smoke test (optional)

From the folder this README lives in:

```bash
python3 -m http.server 8000
# then open http://localhost:8000/
```

Click each card. Each story should load, the character select should appear,
choices should advance scenes, and endings should display with scripture.

---

That's the whole guide. The hardest step is the cPanel upload itself. The rest
is already wired up.
