Compare commits
6 Commits
c34d069d54
...
41050de352
| Author | SHA1 | Date | |
|---|---|---|---|
| 41050de352 | |||
| 1226ea2fbe | |||
| 10d882fce6 | |||
| a9b8900256 | |||
| fc14d37da8 | |||
| b3afd6f9a7 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -39,3 +39,4 @@ yarn-error.log*
|
|||||||
# typescript
|
# typescript
|
||||||
*.tsbuildinfo
|
*.tsbuildinfo
|
||||||
next-env.d.ts
|
next-env.d.ts
|
||||||
|
.superpowers/
|
||||||
|
|||||||
96
app/movie-corner/page.tsx
Normal file
96
app/movie-corner/page.tsx
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
import { Metadata } from "next";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Movie Corner",
|
||||||
|
description:
|
||||||
|
"My personal cinema journal — what I watch and how I feel about it.",
|
||||||
|
};
|
||||||
|
|
||||||
|
const MOVIE_REVIEWS_URL =
|
||||||
|
"https://movies.gabrielkaszewski.dev/users/5d253151-0f6a-4246-9bc5-cb0b5869731b";
|
||||||
|
|
||||||
|
const genres = ["Sci-Fi", "Drama", "Family"];
|
||||||
|
|
||||||
|
export default function MovieCornerPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen flex flex-col pt-20 gravity-body">
|
||||||
|
<section className="py-12 px-4 text-center relative">
|
||||||
|
<div className="absolute inset-0 flex justify-center pointer-events-none">
|
||||||
|
<div className="w-64 h-32 bg-yellow-400/10 blur-3xl rounded-full mt-4" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative">
|
||||||
|
<div className="text-5xl mb-4">🎬</div>
|
||||||
|
|
||||||
|
<h1 className="text-4xl md:text-6xl font-bold tracking-widest text-yellow-400 uppercase mb-3">
|
||||||
|
Movie Corner
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="text-white/60 text-base md:text-lg mb-8">
|
||||||
|
What I watch, what I think. A personal cinema journal.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<blockquote className="border-l-2 border-yellow-400/50 bg-white/5 backdrop-blur-sm rounded-r-lg px-6 py-4 max-w-xl mx-auto text-left mb-8">
|
||||||
|
<p className="text-white/80 text-sm italic leading-relaxed mb-2">
|
||||||
|
“I'd only give one piece of advice to anyone marrying.
|
||||||
|
We're all quite similar in the end. We all get old and tell
|
||||||
|
the same tales too many times. But try and marry someone
|
||||||
|
kind.”
|
||||||
|
</p>
|
||||||
|
<cite className="text-yellow-400/70 text-xs not-italic">
|
||||||
|
— About Time, 2013
|
||||||
|
</cite>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<div className="flex justify-center gap-3 flex-wrap">
|
||||||
|
{genres.map((genre, i) => (
|
||||||
|
<span
|
||||||
|
key={genre}
|
||||||
|
className={`px-4 py-1.5 rounded-full text-sm border ${
|
||||||
|
i === 0
|
||||||
|
? "bg-yellow-400/10 border-yellow-400/40 text-yellow-400"
|
||||||
|
: "bg-white/5 border-white/15 text-white/70"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{genre}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="flex-1 flex flex-col border-t border-white/10 min-h-0 items-center">
|
||||||
|
<div className="flex-1 flex flex-col w-full max-w-[1200px] min-h-0 px-4 py-4">
|
||||||
|
<div
|
||||||
|
className="flex-1 flex flex-col min-h-0 bg-gradient-to-br from-yellow-400/60 via-amber-400/30 to-yellow-400/50 p-[2px] rounded-lg"
|
||||||
|
style={{
|
||||||
|
boxShadow:
|
||||||
|
"0 0 40px rgba(250,204,21,0.2), 0 0 80px rgba(250,204,21,0.08)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="flex-1 overflow-hidden rounded-md flex flex-col">
|
||||||
|
<iframe
|
||||||
|
src={MOVIE_REVIEWS_URL}
|
||||||
|
title="Gabriel's Movie Reviews"
|
||||||
|
allow=""
|
||||||
|
loading="lazy"
|
||||||
|
className="flex-1 min-h-0"
|
||||||
|
style={{ width: "calc(100% + 20px)" }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="py-3 text-center">
|
||||||
|
<a
|
||||||
|
href={MOVIE_REVIEWS_URL}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-yellow-400/70 text-xs hover:text-yellow-400 transition-colors"
|
||||||
|
>
|
||||||
|
Open reviews directly →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -24,6 +24,7 @@ const Navbar = () => {
|
|||||||
{ href: "/", label: "Home" },
|
{ href: "/", label: "Home" },
|
||||||
{ href: "/k-suite", label: "K-Suite" },
|
{ href: "/k-suite", label: "K-Suite" },
|
||||||
{ href: "/projects", label: "Projects" },
|
{ href: "/projects", label: "Projects" },
|
||||||
|
{ href: "/movie-corner", label: "Movie Corner" },
|
||||||
{
|
{
|
||||||
href: "https://blog.gabrielkaszewski.dev/",
|
href: "https://blog.gabrielkaszewski.dev/",
|
||||||
label: "Blog",
|
label: "Blog",
|
||||||
|
|||||||
199
docs/superpowers/plans/2026-05-04-movie-corner.md
Normal file
199
docs/superpowers/plans/2026-05-04-movie-corner.md
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
# Movie Corner Implementation Plan
|
||||||
|
|
||||||
|
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||||
|
|
||||||
|
**Goal:** Add a `/movie-corner` page with a cinematic hero section and a full-height iframe embedding the external movie reviews site.
|
||||||
|
|
||||||
|
**Architecture:** Two-task implementation — navbar link first, then the page itself. The page is a single static component: a fixed-height hero section followed by an iframe that grows to fill all remaining viewport height via flexbox.
|
||||||
|
|
||||||
|
**Tech Stack:** Next.js 15 (App Router), Tailwind CSS v4, TypeScript
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## File Map
|
||||||
|
|
||||||
|
| File | Action | Responsibility |
|
||||||
|
|---|---|---|
|
||||||
|
| `components/navbar.tsx` | Modify | Add "Movie Corner" nav link |
|
||||||
|
| `app/movie-corner/page.tsx` | Create | Full page: metadata + hero + iframe |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Add "Movie Corner" to the navbar
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Modify: `components/navbar.tsx`
|
||||||
|
|
||||||
|
The `navLinks` array currently has: Home, K-Suite, Projects, Blog, About. Insert Movie Corner between Projects and Blog.
|
||||||
|
|
||||||
|
- [ ] **Step 1: Edit `components/navbar.tsx`**
|
||||||
|
|
||||||
|
Find this block:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const navLinks = [
|
||||||
|
{ href: "/", label: "Home" },
|
||||||
|
{ href: "/k-suite", label: "K-Suite" },
|
||||||
|
{ href: "/projects", label: "Projects" },
|
||||||
|
{
|
||||||
|
href: "https://blog.gabrielkaszewski.dev/",
|
||||||
|
label: "Blog",
|
||||||
|
external: true,
|
||||||
|
},
|
||||||
|
{ href: "/about", label: "About" },
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
Replace with:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
const navLinks = [
|
||||||
|
{ href: "/", label: "Home" },
|
||||||
|
{ href: "/k-suite", label: "K-Suite" },
|
||||||
|
{ href: "/projects", label: "Projects" },
|
||||||
|
{ href: "/movie-corner", label: "Movie Corner" },
|
||||||
|
{
|
||||||
|
href: "https://blog.gabrielkaszewski.dev/",
|
||||||
|
label: "Blog",
|
||||||
|
external: true,
|
||||||
|
},
|
||||||
|
{ href: "/about", label: "About" },
|
||||||
|
];
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Type-check**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tsc --noEmit
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: no errors.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add components/navbar.tsx
|
||||||
|
git commit -m "feat: add Movie Corner to navbar"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 2: Create the Movie Corner page
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `app/movie-corner/page.tsx`
|
||||||
|
|
||||||
|
The page is a `min-h-screen flex flex-col` container with `pt-20 gravity-body` (matching all other pages). The hero takes its natural height; the iframe section has `flex-1` so it fills the rest.
|
||||||
|
|
||||||
|
- [ ] **Step 1: Create `app/movie-corner/page.tsx`**
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { Metadata } from "next";
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Movie Corner | Gabriel Kaszewski",
|
||||||
|
description:
|
||||||
|
"My personal cinema journal — what I watch and how I feel about it.",
|
||||||
|
};
|
||||||
|
|
||||||
|
const MOVIE_REVIEWS_URL =
|
||||||
|
"https://movies.gabrielkaszewski.dev/users/5d253151-0f6a-4246-9bc5-cb0b5869731b";
|
||||||
|
|
||||||
|
const genres = ["Sci-Fi", "Drama", "Family"];
|
||||||
|
|
||||||
|
export default function MovieCornerPage() {
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen flex flex-col pt-20 gravity-body">
|
||||||
|
<section className="py-12 px-4 text-center relative">
|
||||||
|
<div className="absolute inset-0 flex justify-center pointer-events-none">
|
||||||
|
<div className="w-64 h-32 bg-yellow-400/10 blur-3xl rounded-full mt-4" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="relative">
|
||||||
|
<div className="text-5xl mb-4">🎬</div>
|
||||||
|
|
||||||
|
<h1 className="text-4xl md:text-6xl font-bold tracking-widest text-yellow-400 uppercase mb-3">
|
||||||
|
Movie Corner
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<p className="text-white/60 text-base md:text-lg mb-8">
|
||||||
|
What I watch, what I think. A personal cinema journal.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<blockquote className="border-l-2 border-yellow-400/50 bg-white/5 backdrop-blur-sm rounded-r-lg px-6 py-4 max-w-xl mx-auto text-left mb-8">
|
||||||
|
<p className="text-white/80 text-sm italic leading-relaxed mb-2">
|
||||||
|
“I'd only give one piece of advice to anyone marrying.
|
||||||
|
We're all quite similar in the end. We all get old and tell
|
||||||
|
the same tales too many times. But try and marry someone
|
||||||
|
kind.”
|
||||||
|
</p>
|
||||||
|
<cite className="text-yellow-400/70 text-xs not-italic">
|
||||||
|
— About Time, 2013
|
||||||
|
</cite>
|
||||||
|
</blockquote>
|
||||||
|
|
||||||
|
<div className="flex justify-center gap-3 flex-wrap">
|
||||||
|
{genres.map((genre, i) => (
|
||||||
|
<span
|
||||||
|
key={genre}
|
||||||
|
className={`px-4 py-1.5 rounded-full text-sm border ${
|
||||||
|
i === 0
|
||||||
|
? "bg-yellow-400/10 border-yellow-400/40 text-yellow-400"
|
||||||
|
: "bg-white/5 border-white/15 text-white/70"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{genre}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section className="flex-1 flex flex-col border-t border-white/10 min-h-0">
|
||||||
|
<iframe
|
||||||
|
src={MOVIE_REVIEWS_URL}
|
||||||
|
title="Gabriel's Movie Reviews"
|
||||||
|
className="flex-1 w-full min-h-0"
|
||||||
|
/>
|
||||||
|
<div className="py-3 text-center">
|
||||||
|
<a
|
||||||
|
href={MOVIE_REVIEWS_URL}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-yellow-400/70 text-xs hover:text-yellow-400 transition-colors"
|
||||||
|
>
|
||||||
|
Open reviews directly →
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- [ ] **Step 2: Type-check**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx tsc --noEmit
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: no errors.
|
||||||
|
|
||||||
|
- [ ] **Step 3: Verify dev server renders the page**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
Open `http://localhost:3000/movie-corner`. Verify:
|
||||||
|
- Navbar shows "Movie Corner" highlighted in yellow
|
||||||
|
- Hero: 🎬 icon, "MOVIE CORNER" title in yellow, tagline, quote card with left yellow border, three genre chips (Sci-Fi yellow, Drama + Family glass)
|
||||||
|
- Iframe fills remaining screen height with the movie reviews site
|
||||||
|
- "Open reviews directly →" link visible at the bottom
|
||||||
|
|
||||||
|
- [ ] **Step 4: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add app/movie-corner/page.tsx
|
||||||
|
git commit -m "feat: add movie-corner page with cinematic hero and embedded reviews"
|
||||||
|
```
|
||||||
80
docs/superpowers/specs/2026-05-04-movie-corner-design.md
Normal file
80
docs/superpowers/specs/2026-05-04-movie-corner-design.md
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
# Movie Corner Page — Design Spec
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
A new `/movie-corner` page on gabrielkaszewski.dev that embeds the user's external movie review site and introduces it with a cinematic hero section.
|
||||||
|
|
||||||
|
## Goals
|
||||||
|
|
||||||
|
- Give the movie review site a home on the personal portfolio
|
||||||
|
- Welcome visitors with personality before showing the embed
|
||||||
|
- Keep the design consistent with the rest of the site (dark glassmorphism, yellow accents, `gravity-body`)
|
||||||
|
|
||||||
|
## Page Structure
|
||||||
|
|
||||||
|
Two vertically stacked sections filling the full viewport height (`min-h-screen flex flex-col`):
|
||||||
|
|
||||||
|
1. **Hero section** — fixed height, centered content
|
||||||
|
2. **Iframe section** — `flex-1`, fills all remaining height
|
||||||
|
|
||||||
|
No page-level scroll after the hero. The iframe scrolls internally.
|
||||||
|
|
||||||
|
## Hero Section
|
||||||
|
|
||||||
|
Centered, padded, with a subtle radial yellow glow behind the icon.
|
||||||
|
|
||||||
|
| Element | Detail |
|
||||||
|
|---|---|
|
||||||
|
| Icon | 🎬 emoji, large |
|
||||||
|
| Title | "MOVIE CORNER", uppercase, yellow (`text-yellow-400`), large tracking |
|
||||||
|
| Tagline | "What I watch, what I think. A personal cinema journal." — muted white |
|
||||||
|
| Quote | Left-bordered card (yellow left border, glass background): *"I'd only give one piece of advice to anyone marrying. We're all quite similar in the end. We all get old and tell the same tales too many times. But try and marry someone kind."* — About Time, 2013 |
|
||||||
|
| Genre chips | Three pills: **Sci-Fi** (yellow tint), **Drama** (white/glass), **Family** (white/glass) |
|
||||||
|
|
||||||
|
The quote card uses `border-l-2 border-yellow-400/50 bg-white/5` consistent with the site's glass style.
|
||||||
|
|
||||||
|
## Iframe Section
|
||||||
|
|
||||||
|
- `flex-1 w-full` — grows to fill remaining page height
|
||||||
|
- `src`: `https://movies.gabrielkaszewski.dev/users/5d253151-0f6a-4246-9bc5-cb0b5869731b`
|
||||||
|
- `title`: "Gabriel's Movie Reviews"
|
||||||
|
- No JS error handling — a permanent **"Open reviews directly →"** text link (yellow, small) sits below the iframe as an always-visible fallback
|
||||||
|
- Thin top border separating hero from iframe (`border-t border-white/10`)
|
||||||
|
|
||||||
|
## Navbar
|
||||||
|
|
||||||
|
Add "Movie Corner" to the `navLinks` array in `components/navbar.tsx`:
|
||||||
|
|
||||||
|
```ts
|
||||||
|
{ href: "/movie-corner", label: "Movie Corner" }
|
||||||
|
```
|
||||||
|
|
||||||
|
Inserted after "Projects" and before "Blog".
|
||||||
|
|
||||||
|
## Metadata
|
||||||
|
|
||||||
|
```ts
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: "Movie Corner | Gabriel Kaszewski",
|
||||||
|
description: "My personal cinema journal — what I watch and how I feel about it.",
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Styling Constraints
|
||||||
|
|
||||||
|
- Use `gravity-body` class on the page root (matches all other pages)
|
||||||
|
- `pt-20` on the page root to clear the fixed navbar
|
||||||
|
- No new CSS — use only existing Tailwind utilities and glass classes already in the project (`backdrop-blur-sm`, `bg-white/5`, `border-white/10`, etc.)
|
||||||
|
|
||||||
|
## Files to Touch
|
||||||
|
|
||||||
|
| File | Change |
|
||||||
|
|---|---|
|
||||||
|
| `app/movie-corner/page.tsx` | Create — full page implementation |
|
||||||
|
| `components/navbar.tsx` | Add "Movie Corner" nav link |
|
||||||
|
|
||||||
|
## Out of Scope
|
||||||
|
|
||||||
|
- Fetching live stats (films watched, avg rating) — static content only
|
||||||
|
- JS error boundary on the iframe
|
||||||
|
- Any backend or API work
|
||||||
Reference in New Issue
Block a user