From abd20c64210d7a78372bb7a88f4113da49b0f1f2 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 10 Jun 2026 11:42:59 +0000 Subject: [PATCH 1/2] Improve design, UX, and site value across all pages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Design: - Fixed glass nav per DESIGN.md spec (blur, hairline, --nav-h token); body offsets by nav height, anchors get matching scroll-margin - Wire up the unused scroll-reveal system: fade-up reveals and staggered list entrances on every page, gated behind html.js and prefers-reduced-motion so content never hides without JS - Amber side-rule + name highlight hover on home plugin rows - Error state styling (destructive border, shake) for newsletter forms UX: - Fix broken skip link (#main-content target never existed); single skip link in BaseLayout, page-level duplicates removed - Plugin detail: dead Install/Watch buttons now link to the install section and community page - Community: sample-session and RSVP buttons now link to the live plugin page and Skool instead of doing nothing - Plugins: "Pitch a plugin" card links to community; hover affordance restricted to cards that are actually links - Subscribe: removed fake "Read →" affordance on archive rows - Subscribe form announces success/error to screen readers (aria-live) - New 404 page in the site voice Value: - JSON-LD structured data: WebSite+Organization (home), ItemList (plugins), SoftwareApplication (plugin detail) - Footer gains internal site links - Link prefetching enabled (prefetchAll) - CLAUDE.md updated to reflect actual site state https://claude.ai/code/session_012ahzoYgJQ4doxZs4ZzNvt8 --- CLAUDE.md | 45 +++++++++------- astro.config.mjs | 1 + package-lock.json | 54 ------------------- src/components/Footer.astro | 20 +++++-- src/components/Nav.astro | 57 ++++++++++++-------- src/layouts/BaseLayout.astro | 5 +- src/pages/404.astro | 46 ++++++++++++++++ src/pages/community.astro | 51 ++++++++++-------- src/pages/index.astro | 95 +++++++++++++++++++++++----------- src/pages/plugins/[slug].astro | 62 ++++++++++++---------- src/pages/plugins/index.astro | 44 +++++++++++----- src/pages/studio.astro | 47 ++++++++--------- src/pages/subscribe.astro | 49 ++++++++---------- src/scripts/subscribe-form.ts | 17 +++++- src/styles/main.css | 67 +++++++++++++++++++++++- 15 files changed, 414 insertions(+), 246 deletions(-) create mode 100644 src/pages/404.astro diff --git a/CLAUDE.md b/CLAUDE.md index cf0bfd1..3320ce5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -2,7 +2,7 @@ Astro 5 → channel47.dev via Vercel. Static output + one serverless endpoint (`api/subscribe.ts`). -**State:** Fresh slate. Pages were nuked May 2026 to start over. Design system is intact. +**State:** Plugins-focused site. Home, plugins library + one detail page, community, studio, subscribe, 404. Link prefetching enabled (`prefetch.prefetchAll`). ## Commands @@ -18,28 +18,32 @@ npm run preview ## Pages -- `/` — placeholder index -- `/api/subscribe` — POST, proxies to Kit API (preserved) +- `/` — home: hero, plugin list, community stat, studio services, subscribe signoff +- `/plugins` — filterable plugin library (8 cards; only `funnel-architect` has a detail page) +- `/plugins/funnel-architect` — plugin detail: meta strip, what's inside, sessions, install block +- `/community` — The Vibe Marketers: stats, sessions calendar (RSVPs link to Skool), member quotes +- `/studio` — client services, case studies, process, contact form +- `/subscribe` — newsletter page with issue archive (titles only — no issue pages exist) +- `/404` — "signal lost" page +- `/api/subscribe` — POST, proxies to Kit API -That's it. Add new pages under `src/pages/`. - -## Design System (the part that survived) +## Structure ``` src/ ├── layouts/ -│ └── BaseLayout.astro # Root layout — meta, fonts, schema, scroll reveal +│ └── BaseLayout.astro # Root layout — meta, fonts, JSON-LD schema, skip link, html.js flag, init scripts ├── components/ -│ ├── Nav.astro # Logo-only fixed nav (links stripped, add back as routes ship) -│ ├── Footer.astro # ctrlswing attribution (links stripped) -│ ├── EmailSignup.astro # 3 variants — inline / default / prominent. Posts to /api/subscribe +│ ├── Nav.astro # Fixed glass nav (blur + hairline). Height = --nav-h; body padding-top offsets it +│ ├── Footer.astro # Internal links + socials, ctrlswing attribution │ ├── LogoAnimated.astro # Animated channel47 logo │ └── Analytics/Analytics.astro ├── styles/ -│ └── main.css # Tailwind v4 @theme tokens, @layer components, keyframes +│ └── main.css # Tailwind v4 @theme tokens, @layer components, reveal styles, keyframes └── scripts/ ├── scroll-reveal.ts # IntersectionObserver scroll reveal - ├── nav-scroll.ts # Nav hide-on-scroll + ├── nav-scroll.ts # Nav hide-on-scroll (currently inert — no .nav--hidden styles defined) + ├── subscribe-form.ts # Enhances [data-kit-form] forms; aria-live status announcements └── copy-to-clipboard.ts # Copy button utility ``` @@ -57,15 +61,18 @@ src/ Tailwind CSS v4 via `@tailwindcss/vite`. Single entry: `src/styles/main.css`. -- `@theme` block defines tokens: warm gray scale, amber accent, font families, radius, animations -- `@layer components` for shared patterns: `.label`, `.wrap`, `.prose`, `.hero`, `.stats`, `.cta`, `.accent-bar` -- Body text is JetBrains Mono. Single accent: amber `#F59E0B` -- shadcn/ui semantic tokens (`background`, `foreground`, `ring`, etc.) defined in `@theme` for React component compatibility +- `@theme` block defines tokens: `bg`/`surface`/`text`/`line` scale, amber accent, font families, radius +- `@layer components` for shared patterns: `.wrap`, `.eyebrow`, `.amber`, `.btn-primary`, `.btn-ghost`, `.head-hero`, `.head-section`, `.head-mid`, `.body-lead`, `.body-mid`, `.section-pad`, `.skip-link`, `.visually-hidden` +- Body text is Geist sans; Geist Mono for code/indices. Single accent: amber `#F5B544` +- `--nav-h` (`:root`) sizes the fixed nav; `body` gets `padding-top: var(--nav-h)` and `[id]` gets matching `scroll-margin-top` +- shadcn/ui semantic tokens (`background`, `foreground`, `ring`) defined in `@theme` for React component compatibility -## Scroll Reveals (two layers) +## Scroll Reveals -1. **Section-level**: `data-section="name"` + IO (threshold 0.15). Adds `.is-visible`. -2. **Element-level**: `BaseLayout` observes `[data-animate]` (threshold 0.1). One-time. Stagger with `data-stagger="1..6"`. +- `data-reveal` — single element, fades up when 12% visible. One-time. +- `data-reveal-stagger` (parent) + `data-reveal-child` (children) — children reveal together with per-child delay via inline `style="--stagger: n"` (capped at 5 in CSS). +- Hidden states are gated behind `html.js` (set inline in BaseLayout ``) and `prefers-reduced-motion: no-preference` — content stays visible without JS or with reduced motion. +- Legacy `data-section` / `data-animate` observers still run but no page uses them. ## Schema (structured data) diff --git a/astro.config.mjs b/astro.config.mjs index ae31fc7..d552b9a 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -7,6 +7,7 @@ import react from '@astrojs/react'; export default defineConfig({ site: 'https://channel47.dev', output: 'static', + prefetch: { prefetchAll: true }, adapter: vercel({ webAnalytics: { enabled: true diff --git a/package-lock.json b/package-lock.json index cbc0025..3cca9a8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,6 @@ "version": "0.0.1", "dependencies": { "@astrojs/react": "^4.4.2", - "@astrojs/rss": "^4.0.15", "@astrojs/sitemap": "^3.6.1", "@astrojs/vercel": "^9.0.3", "@radix-ui/react-slot": "^1.2.3", @@ -104,16 +103,6 @@ "react-dom": "^17.0.2 || ^18.0.0 || ^19.0.0" } }, - "node_modules/@astrojs/rss": { - "version": "4.0.15", - "resolved": "https://registry.npmjs.org/@astrojs/rss/-/rss-4.0.15.tgz", - "integrity": "sha512-uXO/k6AhRkIDXmRoc6xQpoPZrimQNUmS43X4+60yunfuMNHtSRN5e/FiSi7NApcZqmugSMc5+cJi8ovqgO+qIg==", - "license": "MIT", - "dependencies": { - "fast-xml-parser": "^5.3.3", - "piccolore": "^0.1.3" - } - }, "node_modules/@astrojs/sitemap": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/@astrojs/sitemap/-/sitemap-3.7.0.tgz", @@ -4031,37 +4020,6 @@ "license": "MIT", "optional": true }, - "node_modules/fast-xml-builder": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.0.0.tgz", - "integrity": "sha512-fpZuDogrAgnyt9oDDz+5DBz0zgPdPZz6D4IR7iESxRXElrlGTRkHJ9eEt+SACRJwT0FNFrt71DFQIUFBJfX/uQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT" - }, - "node_modules/fast-xml-parser": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.4.1.tgz", - "integrity": "sha512-BQ30U1mKkvXQXXkAGcuyUA/GA26oEB7NzOtsxCDtyu62sjGw5QraKFhx2Em3WQNjPw9PG6MQ9yuIIgkSDfGu5A==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT", - "dependencies": { - "fast-xml-builder": "^1.0.0", - "strnum": "^2.1.2" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -6748,18 +6706,6 @@ "node": ">=8" } }, - "node_modules/strnum": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.2.0.tgz", - "integrity": "sha512-Y7Bj8XyJxnPAORMZj/xltsfo55uOiyHcU2tnAVzHUnSJR/KsEX+9RoDeXEnsXtl/CX4fAcrt64gZ13aGaWPeBg==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT" - }, "node_modules/svgo": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/svgo/-/svgo-4.0.0.tgz", diff --git a/src/components/Footer.astro b/src/components/Footer.astro index f6f4de5..d4d1460 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -1,9 +1,21 @@ --- const year = new Date().getFullYear(); + +const siteLinks = [ + { label: 'Plugins', href: '/plugins' }, + { label: 'Community', href: '/community' }, + { label: 'Studio', href: '/studio' }, + { label: 'Subscribe', href: '/subscribe' }, +]; ---