From 2f27cb86c468c383c04550c5e3035b5dde16cebe Mon Sep 17 00:00:00 2001
From: Dorian
Date: Tue, 3 Mar 2026 00:27:51 +0000
Subject: [PATCH] wip: magazine tile layout, film descriptions, dev script
fixes
- MagazineGrid: New Yorker tile layout with wide/half/dark/banner tiles
- Extract AI film descriptions into synopsis field
- Fix section extraction to handle ### headers
- Strip emojis from magazine titles and content
- FilmDetail: conditional synopsis with "Why watch" header
- FilmCard: synopsis preview for external films
- Consolidate dev server to single script
- Fix dev.sh for macOS bash 3.2 compatibility
Co-Authored-By: Claude Opus 4.6
---
.claude/launch.json | 13 +-
packages/app/scripts/dev.sh | 19 +-
.../app/src/components/content/FilmCard.vue | 5 +
.../app/src/components/content/FilmDetail.vue | 23 +-
.../src/components/content/MagazineGrid.vue | 414 ++++++++++--------
packages/app/src/composables/useAI.ts | 2 +-
.../app/src/composables/useContentPanel.ts | 50 ++-
7 files changed, 313 insertions(+), 213 deletions(-)
diff --git a/.claude/launch.json b/.claude/launch.json
index 6f3007ab..f7e736a4 100644
--- a/.claude/launch.json
+++ b/.claude/launch.json
@@ -2,18 +2,11 @@
"version": "0.0.1",
"configurations": [
{
- "name": "app",
- "runtimeExecutable": "pnpm",
- "runtimeArgs": ["--filter", "@aiui/app", "dev:vite"],
+ "name": "dev",
+ "runtimeExecutable": "bash",
+ "runtimeArgs": ["packages/app/scripts/dev.sh"],
"port": 5173,
"autoPort": true
- },
- {
- "name": "claude-proxy",
- "runtimeExecutable": "pnpm",
- "runtimeArgs": ["--filter", "@aiui/app", "dev:proxy"],
- "port": 3141,
- "autoPort": true
}
]
}
diff --git a/packages/app/scripts/dev.sh b/packages/app/scripts/dev.sh
index ff3eebfe..d2aecc31 100755
--- a/packages/app/scripts/dev.sh
+++ b/packages/app/scripts/dev.sh
@@ -7,23 +7,24 @@ set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
APP_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
+cd "$APP_DIR"
+
cleanup() {
- # Kill all child processes
kill 0 2>/dev/null || true
wait 2>/dev/null || true
}
trap cleanup EXIT INT TERM
+# Use local node_modules binaries
+BIN="$APP_DIR/node_modules/.bin"
+
# Start Claude proxy in background
-npx tsx "$APP_DIR/server/claude-proxy.ts" &
-PROXY_PID=$!
+"$BIN/tsx" server/claude-proxy.ts &
-# Give proxy a moment to bind port
sleep 0.3
-# Start Vite dev server in foreground
-npx vite --host &
-VITE_PID=$!
+# Start Vite dev server in background
+"$BIN/vite" --host &
-# Wait for either to exit — then cleanup kills both
-wait -n $PROXY_PID $VITE_PID 2>/dev/null || true
+# Wait for all background jobs (compatible with bash 3.2 on macOS)
+wait
diff --git a/packages/app/src/components/content/FilmCard.vue b/packages/app/src/components/content/FilmCard.vue
index fbbc3917..99725a87 100644
--- a/packages/app/src/components/content/FilmCard.vue
+++ b/packages/app/src/components/content/FilmCard.vue
@@ -29,6 +29,11 @@
:class="isDark ? 'text-white/40' : 'text-gray-500'">
{{ film.year }} · {{ film.director }}
+
+ {{ film.synopsis }}
+
-
+
-
- {{ film.synopsis }}
-
+
+
+ Why watch
+
+
+ {{ film.synopsis }}
+
+
-
+
-
+
Watch on
@@ -106,6 +113,8 @@ defineEmits<{ back: [] }>()
const { isDark } = useTheme()
+const isExternal = computed(() => props.film.id.startsWith('ext-'))
+
// Fallback order: backdrop (mock) → TMDB API → poster (mock) → gradient
const bannerTry = ref<'backdrop' | 'tmdb' | 'poster' | 'done'>('backdrop')
const tmdbBannerUrl = ref
(null)
diff --git a/packages/app/src/components/content/MagazineGrid.vue b/packages/app/src/components/content/MagazineGrid.vue
index 9ea11687..82f605b9 100644
--- a/packages/app/src/components/content/MagazineGrid.vue
+++ b/packages/app/src/components/content/MagazineGrid.vue
@@ -1,13 +1,11 @@
-
-
-
-
+
+
+
AI Brief
@@ -15,146 +13,108 @@
-