diff --git a/docs/superpowers/plans/2026-05-16-frutiger-aero-redesign.md b/docs/superpowers/plans/2026-05-16-frutiger-aero-redesign.md
new file mode 100644
index 0000000..cb56b36
--- /dev/null
+++ b/docs/superpowers/plans/2026-05-16-frutiger-aero-redesign.md
@@ -0,0 +1,1198 @@
+# Thoughts Frontend — Frutiger Aero Redesign 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:** Apply the Frutiger Aero aesthetic throughout `thoughts-frontend` — glass panels, gloss sweeps, Aero shimmer, gradient avatars, and delightful interaction moments (particle bursts, shake+fade, slide-in forms).
+
+**Architecture:** Component-by-component update. CSS keyframes and utility classes go in `globals.css` first (foundation). UI primitives (badge, skeleton) are updated next. Then page-level components (header, landing). Then feed components (cards, widgets). Then interaction moments (follow burst, delete animation). Every task ends with a build check and a commit.
+
+**Tech Stack:** Next.js 15 (App Router), React 19, TypeScript, Tailwind CSS v4, shadcn/ui, Bun
+
+**Build check command (run after every task):**
+```bash
+cd thoughts-frontend && bun run build
+```
+
+**Spec:** `docs/superpowers/specs/2026-05-16-thoughts-frutiger-aero-redesign-design.md`
+
+---
+
+## Pre-flight: verify current build passes
+
+- [ ] Run `cd thoughts-frontend && bun run build` — must be green before starting
+
+---
+
+## Task 1: CSS keyframes and utility classes
+
+**Files:**
+- Modify: `thoughts-frontend/app/globals.css`
+
+Add after the last `@layer components { }` block.
+
+- [ ] **Step 1: Append keyframes and utilities to `globals.css`**
+
+Add this block at the end of the file:
+
+```css
+/* ── Frutiger Aero interaction keyframes ── */
+@keyframes slideDown {
+ from {
+ opacity: 0;
+ transform: translateY(-8px);
+ max-height: 0;
+ overflow: hidden;
+ }
+ to {
+ opacity: 1;
+ transform: translateY(0);
+ max-height: 300px;
+ overflow: hidden;
+ }
+}
+
+@keyframes shake {
+ 0%, 100% { transform: translateX(0) rotate(0deg); }
+ 15% { transform: translateX(-4px) rotate(-1.5deg); }
+ 30% { transform: translateX(4px) rotate(1.5deg); }
+ 45% { transform: translateX(-3px) rotate(-1deg); }
+ 60% { transform: translateX(3px) rotate(1deg); }
+ 75% { transform: translateX(-1px) rotate(-0.5deg); }
+}
+
+@keyframes fadeOut {
+ from { opacity: 1; transform: scale(1) translateY(0); }
+ to { opacity: 0; transform: scale(0.9) translateY(8px); }
+}
+
+@keyframes floatBob {
+ 0%, 100% { transform: translateY(0); }
+ 50% { transform: translateY(-6px); }
+}
+
+@keyframes shimmerAero {
+ 0% { background-position: -400px 0; }
+ 100% { background-position: 400px 0; }
+}
+
+@layer components {
+ .animate-slide-down {
+ animation: slideDown 0.22s ease-out forwards;
+ }
+ .animate-shake {
+ animation: shake 0.45s ease-out;
+ }
+ .animate-fade-out {
+ animation: fadeOut 0.3s ease-out forwards;
+ }
+ .animate-float-bob {
+ animation: floatBob 2.8s ease-in-out infinite;
+ }
+
+ /* Aero-tinted shimmer for skeleton loaders */
+ .shimmer-aero {
+ background: linear-gradient(
+ 90deg,
+ rgba(96, 165, 250, 0.12) 25%,
+ rgba(96, 165, 250, 0.30) 50%,
+ rgba(96, 165, 250, 0.12) 75%
+ );
+ background-size: 800px 100%;
+ animation: shimmerAero 1.5s infinite linear;
+ }
+
+ /* Widget title icon badges */
+ .widget-icon {
+ width: 22px;
+ height: 22px;
+ border-radius: 8px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 12px;
+ flex-shrink: 0;
+ }
+ .widget-icon-blue {
+ background: linear-gradient(135deg, #60a5fa, #2563eb);
+ box-shadow: 0 2px 4px rgba(37, 99, 235, 0.3),
+ inset 0 1px 1px rgba(255, 255, 255, 0.3);
+ }
+ .widget-icon-green {
+ background: linear-gradient(135deg, #6ee7b7, #10b981);
+ box-shadow: 0 2px 4px rgba(16, 185, 129, 0.3),
+ inset 0 1px 1px rgba(255, 255, 255, 0.3);
+ }
+ .widget-icon-purple {
+ background: linear-gradient(135deg, #c4b5fd, #7c3aed);
+ box-shadow: 0 2px 4px rgba(124, 58, 237, 0.3),
+ inset 0 1px 1px rgba(255, 255, 255, 0.3);
+ }
+
+ /* Landing page ambient orbs */
+ .orb {
+ position: absolute;
+ border-radius: 50%;
+ filter: blur(40px);
+ opacity: 0.45;
+ pointer-events: none;
+ }
+
+ /* Gradient avatar fallback */
+ .avatar-gradient {
+ background: linear-gradient(135deg, #60a5fa, #34d399);
+ box-shadow: 0 0 0 2px white, 0 0 0 3.5px rgba(59, 130, 246, 0.45);
+ }
+}
+
+/* Respect reduced motion */
+@media (prefers-reduced-motion: reduce) {
+ .animate-slide-down { animation: none; }
+ .animate-shake { animation: none; }
+ .animate-fade-out { animation: none; }
+ .animate-float-bob { animation: none; }
+ .shimmer-aero {
+ animation: none;
+ background: rgba(96, 165, 250, 0.18);
+ }
+}
+```
+
+- [ ] **Step 2: Build check**
+
+```bash
+cd thoughts-frontend && bun run build
+```
+
+Expected: build succeeds with no errors.
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add thoughts-frontend/app/globals.css
+git commit -m "feat: add FA keyframes and utility classes to globals.css"
+```
+
+---
+
+## Task 2: Badge `branded` and `trending` variants
+
+**Files:**
+- Modify: `thoughts-frontend/components/ui/badge.tsx`
+
+- [ ] **Step 1: Add variants to `badgeVariants` in `badge.tsx`**
+
+Replace the `variants` object inside `cva(...)`:
+
+```tsx
+variants: {
+ variant: {
+ default:
+ "border-transparent bg-primary text-primary-foreground hover:bg-primary/80 glossy-effect bottom text-shadow-sm",
+ secondary:
+ "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80 glossy-effect bottom text-shadow-sm",
+ destructive:
+ "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80 glossy-effect bottom text-shadow-sm",
+ outline: "text-foreground glossy-effect bottom text-shadow-sm",
+ branded:
+ "border border-primary/20 bg-primary/8 text-primary font-semibold hover:bg-primary/15 hover:scale-105 transition-transform cursor-pointer",
+ trending:
+ "border border-red-300/30 bg-gradient-to-r from-orange-500/10 to-red-500/8 text-red-600 font-semibold hover:from-orange-500/18 hover:to-red-500/14 hover:scale-105 transition-transform cursor-pointer",
+ },
+},
+```
+
+- [ ] **Step 2: Build check**
+
+```bash
+cd thoughts-frontend && bun run build
+```
+
+Expected: build succeeds.
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add thoughts-frontend/components/ui/badge.tsx
+git commit -m "feat: add branded and trending badge variants"
+```
+
+---
+
+## Task 3: Skeleton Aero shimmer
+
+**Files:**
+- Modify: `thoughts-frontend/components/ui/skeleton.tsx`
+
+- [ ] **Step 1: Read current `skeleton.tsx`**
+
+```bash
+cat thoughts-frontend/components/ui/skeleton.tsx
+```
+
+- [ ] **Step 2: Replace the file with Aero shimmer version**
+
+```tsx
+import * as React from "react"
+import { cn } from "@/lib/utils"
+
+function Skeleton({ className, ...props }: React.ComponentProps<"div">) {
+ return (
+
+ )
+}
+
+export { Skeleton }
+```
+
+- [ ] **Step 3: Build check**
+
+```bash
+cd thoughts-frontend && bun run build
+```
+
+- [ ] **Step 4: Commit**
+
+```bash
+git add thoughts-frontend/components/ui/skeleton.tsx
+git commit -m "feat: apply Aero shimmer to skeleton loader"
+```
+
+---
+
+## Task 4: UserAvatar — gradient fallback + glow ring
+
+**Files:**
+- Modify: `thoughts-frontend/components/user-avatar.tsx`
+
+Current: fallback is a generic `` icon, border is `border-primary/50`.
+
+- [ ] **Step 1: Update `user-avatar.tsx`**
+
+```tsx
+import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
+import { cn } from "@/lib/utils";
+
+interface UserAvatarProps {
+ src?: string | null;
+ alt?: string | null;
+ className?: string;
+}
+
+export function UserAvatar({ src, alt, className }: UserAvatarProps) {
+ const initial = alt?.trim()[0]?.toUpperCase() ?? "?";
+
+ return (
+
+ {src && (
+
+ )}
+
+ {initial}
+
+
+ );
+}
+```
+
+- [ ] **Step 2: Build check**
+
+```bash
+cd thoughts-frontend && bun run build
+```
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add thoughts-frontend/components/user-avatar.tsx
+git commit -m "feat: gradient avatar fallback with initials and glow ring"
+```
+
+---
+
+## Task 5: EmptyState redesign
+
+**Files:**
+- Modify: `thoughts-frontend/components/empty-state.tsx`
+
+Current: renders a single `` with the message string.
+
+- [ ] **Step 1: Rewrite `empty-state.tsx`**
+
+```tsx
+import Link from "next/link";
+
+interface EmptyStateProps {
+ emoji?: string;
+ title?: string;
+ message: string;
+ ctaLabel?: string;
+ ctaHref?: string;
+ className?: string;
+}
+
+export function EmptyState({
+ emoji = "💭",
+ title,
+ message,
+ ctaLabel,
+ ctaHref,
+ className = "",
+}: EmptyStateProps) {
+ return (
+
+
+ {emoji}
+
+ {title && (
+
{title}
+ )}
+
{message}
+ {ctaLabel && ctaHref && (
+
+ {ctaLabel}
+
+ )}
+
+ );
+}
+```
+
+- [ ] **Step 2: Update all call sites to pass the new props**
+
+Search for existing usages:
+```bash
+grep -rn "EmptyState" thoughts-frontend/app --include="*.tsx"
+```
+
+For each usage, add an `emoji` and `title` appropriate to the context. For example in `app/page.tsx`:
+
+```tsx
+
+```
+
+For search (`app/search/page.tsx`) — check the file and use `emoji="🔍" title="No results"`.
+
+For tags — use `emoji="🏷" title="No thoughts here yet"`.
+
+- [ ] **Step 3: Build check**
+
+```bash
+cd thoughts-frontend && bun run build
+```
+
+Expected: no TypeScript errors — `message` is still required, other props are optional.
+
+- [ ] **Step 4: Commit**
+
+```bash
+git add thoughts-frontend/components/empty-state.tsx thoughts-frontend/app
+git commit -m "feat: redesign EmptyState with floating emoji and optional CTA"
+```
+
+---
+
+## Task 6: Header — logo bubble + pill buttons
+
+**Files:**
+- Modify: `thoughts-frontend/components/header.tsx`
+
+Current: plain text "Thoughts", flat Login/Register buttons.
+
+- [ ] **Step 1: Rewrite `header.tsx`**
+
+```tsx
+"use client";
+
+import { useAuth } from "@/hooks/use-auth";
+import Link from "next/link";
+import { Button } from "./ui/button";
+import { UserNav } from "./user-nav";
+import { MainNav } from "./main-nav";
+
+export function Header() {
+ const { token } = useAuth();
+
+ return (
+
+ );
+}
+```
+
+- [ ] **Step 2: Build check**
+
+```bash
+cd thoughts-frontend && bun run build
+```
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add thoughts-frontend/components/header.tsx
+git commit -m "feat: add logo bubble and pill buttons to header"
+```
+
+---
+
+## Task 7: Landing page — orbs, deeper glass, fediverse badge
+
+**Files:**
+- Modify: `thoughts-frontend/app/page.tsx` (the `LandingPage` function only)
+
+- [ ] **Step 1: Replace the `LandingPage` function**
+
+Find and replace the entire `LandingPage` function (lines 122–148):
+
+```tsx
+function LandingPage() {
+ return (
+
+ {/* Ambient orbs */}
+
+
+
+
+ {/* Hero card */}
+
+ {/* Gloss sweep */}
+
+
+
+ Welcome to Thoughts ✨
+
+
+ A federated social network for short-form thoughts.
+ Connect with the Fediverse.
+
+
+
+
+
+
+
+ {/* Fediverse badge */}
+
+
+
+ Works with Mastodon, Pixelfed & more
+
+
+
+
+ );
+}
+```
+
+- [ ] **Step 2: Build check**
+
+```bash
+cd thoughts-frontend && bun run build
+```
+
+- [ ] **Step 3: Commit**
+
+```bash
+git add thoughts-frontend/app/page.tsx
+git commit -m "feat: redesign landing page with ambient orbs and fediverse badge"
+```
+
+---
+
+## Task 8: Thought card — hover lift, reply button pill, hashtag coloring
+
+**Files:**
+- Modify: `thoughts-frontend/components/thought-card.tsx`
+
+- [ ] **Step 1: Add `renderWithHashtags` helper before the component**
+
+Add this function just above the `ThoughtCard` function declaration:
+
+```tsx
+function renderWithHashtags(content: string) {
+ return content.split(/(#\w+)/g).map((part, i) =>
+ /^#\w+$/.test(part) ? (
+
+ {part}
+
+ ) : (
+ part
+ )
+ );
+}
+```
+
+- [ ] **Step 2: Add hover lift to the `` element**
+
+Find the `` line and change it to:
+
+```tsx
+
+```
+
+- [ ] **Step 3: Replace the Reply `