Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,26 @@ configuration for the Claude Code project settings.
├── .claude/
│ └── settings.json # Claude Code project configuration
├── setup.sh # One-shot setup script
├── site-kit/ # CCC Site Kit scripts (see site-kit/README.md)
│ ├── build.sh
│ ├── deploy.sh
│ ├── use-stock.sh
│ └── README.md
└── README.md
```

---

## site-kit/

`site-kit/` holds the CCC Site Kit shell scripts and their README. It is
independent of the Hermes setup above.

Only the shell scripts and the README are present. The kit's README also refers
to `site.config.mjs`, `render.mjs`, `stamp.mjs`, and the `engine/`, `templates/`,
`render/`, `reference/`, and `stock/` folders, none of which are in this
repository yet, so the scripts are not runnable as-is.

The scripts also assume a macOS shell environment: they use `#!/bin/zsh`, and
`build.sh` calls `sips` (macOS only) plus `ffmpeg`, `ffprobe`, and `bc` without
checking that they exist.
51 changes: 51 additions & 0 deletions site-kit/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# CCC Site Kit

Build a $10k-class animated website for any brand. The engine gives you the quality floor; you supply one config and your assets.

## Quickstart

The easy way: open Claude Code in this folder and run **`/build-site`**. It interviews you, fills `site.config.mjs`, renders your assets, and ships the site.

The manual way:

```bash
# 1. Edit site.config.mjs — your brand, palette, copy, style, and render prompts.

# 2. Render your 2 videos + 3 images (needs a fal.ai key):
FAL_KEY=your_key node render.mjs
# ...or no key? use a stock set: ./use-stock.sh warm <your-slug>

# 3. Build:
./build.sh

# 4. Preview:
cd dist && python3 -m http.server 8000 # then open /<slug>/

# 5. Ship it live (one command):
./deploy.sh
```

### Hosting: no Cloudinary, no third-party media host
Your built site lives in `dist/<slug>/` and is **fully self-contained** — the HTML, the engine, and every video and image are in that one folder. It deploys like any static site: `./deploy.sh` pushes it to Vercel, or drag the folder onto [Netlify Drop](https://app.netlify.com/drop). The videos play because they ship right next to the page.

## What's in here

| Folder | What it is | Touch it? |
|---|---|---|
| `engine/` | premium2.css + premium2.js — living scrub, footer FX, mesh, legibility, the no-duplication spine | **No** |
| `templates/` | the spine + style variants (A–G) | No |
| `render/` | gen-image / gen-motion / gen-transform (Nano Banana + Seedance) | No |
| `reference/` | the style catalog + design laws | Read |
| `stock/` | fallback videos + images if you have no fal key | Use |
| `site.config.mjs` | **your brand, copy, palette, style, render prompts** | **Yes — this is yours** |
| `dist/` | the built site | Output |

## The standard (baked in, so every site clears the bar)
- 7 scroll styles: A loop · B scrub · C cursor · D horizontal · E exploded · F push-through · G scrollytelling.
- Every site = 2 videos + 3 images, each used exactly once. No duplication.
- Living scrub (heroes keep moving when idle), legibility halo, mesh background, animated footer.
- OKLCH color, no `#000`/`#fff`, one accent, no em dashes.

Customizing is a conversation: tell Claude "darker," "exploded style," "new headline," and it edits the config and rebuilds. Copy changes never need a re-render.

Built by Claude Code Club · claudecodeclub.ai
34 changes: 34 additions & 0 deletions site-kit/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/zsh
# build.sh — wires rendered assets + stamps the config onto the engine.
# Run AFTER `node render.mjs` (or after ./use-stock.sh dropped stock into work/<slug>/).
cd "$(dirname "$0")"
slug=$(node -e "import('./site.config.mjs').then(m=>process.stdout.write(m.default.slug))")
style=$(node -e "import('./site.config.mjs').then(m=>process.stdout.write(m.default.style||'B'))")
A="dist/$slug/assets"; W="work/$slug"
mkdir -p "$A/sec"

if [ "$style" = "A" ]; then
# Style A: ambient loop hero — use the video directly, no frame extraction
cp "$W/hero/hero.mp4" "$A/hero.mp4"
ffmpeg -y -loglevel error -i "$W/hero/hero.mp4" -frames:v 1 -vf "scale=1600:-2" "$A/still.jpg"
else
# B/C/D/E/F/G: hero scrub frames from video 1
mkdir -p "$A/frames"; rm -f "$A/frames"/[0-9]*.jpg 2>/dev/null
src="$W/hero/hero.mp4"
dur=$(ffprobe -v error -show_entries format=duration -of csv=p=0 "$src")
fps=$(echo "scale=4;120/$dur" | bc)
ffmpeg -y -loglevel error -i "$src" -vf "fps=$fps,scale=1600:-2" -frames:v 120 "$A/frames/tmp_%03d.jpg"
i=1; for f in "$A/frames"/tmp_*.jpg; do mv "$f" "$A/frames/$(printf '%04d' $i).jpg"; i=$((i+1)); done
w=$(sips -g pixelWidth "$A/frames/0001.jpg" | awk '/pixelWidth/{print $2}')
h=$(sips -g pixelHeight "$A/frames/0001.jpg" | awk '/pixelHeight/{print $2}')
printf '{"count":120,"w":%s,"h":%s}' "$w" "$h" > "$A/frames/manifest.json"
cp "$A/frames/0001.jpg" "$A/still.jpg"
fi

# video 2 -> middle band loop (every style)
cp "$W/middle/hero.mp4" "$A/sec/hero.mp4"
# 3 images
cp "$W/g1.jpg" "$A/g1.jpg"; cp "$W/g2.jpg" "$A/g2.jpg"; cp "$W/g3.jpg" "$A/g3.jpg"

node stamp.mjs
echo "BUILD DONE ($style) -> dist/$slug/ (serve dist/ and open /$slug/)"
21 changes: 21 additions & 0 deletions site-kit/deploy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#!/bin/zsh
# deploy.sh — publish your site live in one command.
# Your built site (dist/<slug>/) is SELF-CONTAINED: the HTML, the engine, and every
# video and image are in that one folder. No Cloudinary, no external media host needed.
# It deploys like any static folder.
cd "$(dirname "$0")"
slug=$(node -e "import('./site.config.mjs').then(m=>process.stdout.write(m.default.slug))")
dir="dist/$slug"
[ -d "$dir" ] || { echo "Nothing built yet. Run ./build.sh first."; exit 1; }

echo "Publishing $dir ..."
echo "(first run will ask you to log in to Vercel — free)"
npx --yes vercel@latest deploy "$dir" --prod --yes

cat <<'NOTE'

No CLI? Two zero-setup alternatives:
- Netlify Drop: open app.netlify.com/drop and drag the dist/<slug> folder onto the page.
- GitHub Pages: push dist/<slug> to a repo and enable Pages.
Everything in that folder ships together. Your videos will play because they are right there next to the page.
NOTE
12 changes: 12 additions & 0 deletions site-kit/use-stock.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/zsh
# use-stock.sh <set> <slug> e.g. ./use-stock.sh warm mybrand
cd "$(dirname "$0")"
set=$1; slug=$2
[ -d "stock/$set" ] || { echo "no stock set '$set' (have: $(ls stock))"; exit 1; }
mkdir -p "work/$slug/hero" "work/$slug/middle"
cp "stock/$set/hero.mp4" "work/$slug/hero/hero.mp4"
cp "stock/$set/middle.mp4" "work/$slug/middle/hero.mp4"
cp "stock/$set/g1.jpg" "work/$slug/g1.jpg"
cp "stock/$set/g2.jpg" "work/$slug/g2.jpg"
cp "stock/$set/g3.jpg" "work/$slug/g3.jpg"
echo "stock set '$set' -> work/$slug/ (now run ./build.sh)"