A template.tsx is re-created on every navigation, resetting AnimatePresence
so neither enter nor exit ran. Move the transition into a PageTransition
client component rendered in the persistent (site) layout, so AnimatePresence
survives navigations and the old page animates out before the new one in.
- Bring back the corner fan-out controls; drop the in-dock settings tile.
- Regenerate public/dock/*.svg so the squircle fills the whole tile with
no inner margin.
Replace the custom radial corner menu with in-dock control tiles so the
whole bar reads as one macOS dock: logo | pages | settings, each group
divided by a separator. Controls reuse the existing toggle components on
graphite squircle tiles matching the page icons.
- Dock icons are now real SVG files under public/dock/ (macOS squircle
look, active variants), so they can be replaced with custom art later.
- Full-bleed icons (DockIcon padding 0), fixed logo src to stop the
refresh flash.
- Remove the top menu bar entirely; relocate theme/language/sound (+admin)
into a corner control dock that expands on click.
Swap the pill navigation for a macOS-style dock as the primary nav and a
slim top menu bar for utilities:
- components/ui/dock.tsx: Magic UI Dock/DockIcon (magnification via
useSpring/useTransform), ported to the project's framer-motion.
- components/layout/site-dock.tsx: bottom dock with the logo as the first
icon, each item a real next/link (SEO preserved, active state from the
pathname), monochrome squircle tiles, hover tooltips and a "soon" badge
for Products; top menu bar keeps locale/sound/theme/admin + a live clock.
- (site)/layout.tsx: render SiteDock instead of SiteHeader.
Home bento grid and all page content are unchanged.
Merge the category and project routes under a single /portfolio/[slug]
segment via resolvePortfolioSlug (category wins over project on a slug
clash). Removes the /portfolio/category/... prefix from links, redirect,
and sitemap. Adds resolver integration tests.
Replace the framer-motion hero entrance with pure-CSS staggered animations so
the hero is painted immediately instead of flashing blank until hydration.
Add a focused brand glow behind the hero title and an animated scroll cue at
the bottom of the home hero. Entrance and cue respect prefers-reduced-motion.
Replace the flat, empty hero background with a pure-CSS layered backdrop:
faded grid, brand glow, drifting brand orbs, grain, and a bottom fade that
blends the hero into page content. Applies to both the home hero and the
compact page heroes via HeroMotionBackdrop; respects prefers-reduced-motion.
Replace the flat two-column layout with a guided 4-step wizard
(Grundlagen -> Inhalte -> Abschnitte -> Medien) using the existing wizard
progress model:
- A top stepper shows each step's number/label and completion (check), and
jumps to any step on click.
- One step is visible at a time in a single comfortable centered column; the
others stay mounted but hidden, so every named field still submits.
- Footer navigation: Zurueck / Save as draft / Weiter, with Save Project on
the final step.
No field-name or save-logic changes. All 375 tests pass; tsc and eslint clean.
Experiment: remove the AppCard wrappers around Basic Information, Localized
Content, Sections and Cover/Assets, plus the action bar, so the form content
sits directly on the page. Section headers now carry a thin underline and the
action bar a top divider to keep structure without card chrome. Two-column
layout preserved. No field-name or save-logic changes.
- Remove the project summary/header card (project name, badges, progress);
it added no value while creating a project. Move the on-submit validation
alert down to the action bar.
- Lay the whole form out in two columns: Basic Information + Localized
Content, then Sections + Cover/Assets. Basic Information fields cap at two
columns and the Cover/Assets card stacks inside its column.
All 375 tests pass; tsc and eslint clean.
Fix the deeply nested cards in the project form (screenshot: Cover Media >
Cover > preview card, with duplicate labels):
- MediaFieldPicker no longer wraps itself in AppCards. It renders one flat
bordered box laid out in two columns (preview | controls), dropping two
nested card layers and the duplicate title.
- Cover Media and Assets now sit side by side in a two-column grid instead
of stacked with a separator.
All 375 tests pass; tsc and eslint clean.
Reorganize the project form for a lighter, more professional flow without
touching field names or the save action (all data preserved):
- LocaleInputs: drop the per-locale card wrappers for a tight 3-column
labelled grid; shorter textareas.
- Sections and Assets: collapse each item into an accordion (closed by
default) and show a proper empty state when there are none.
- Slim the header to badges + title + a compact progress indicator instead
of a stats grid; drop the assets stats sidebar.
- Tighten section paddings/spacing (lg -> md) throughout.
All 375 tests pass; tsc and eslint clean.
Replace the card grid with a compact data table (cover, project, category,
year, status, layout, actions) and a proper empty state that adapts to an
active category filter. Actions expose a public-view link plus the existing
edit/delete menu. No data-layer or save changes.
The double-layer AppCard look showcased in the UI Kit was only applied on
the public frontend; every admin surface was pinned to layer=single and
stayed flat. Convert the admin section/container cards to the default
layered look, keeping compact metric tiles, toolbars, image tiles and
nested leaf cards single.
Add AppCard contentClassName so content utilities (space-y-*, grid, flex)
keep applying to the inner shell after the switch to double layer.
- Add a Save as draft button that bypasses the completeness gate: the user
can save partial work and finish later
- projectDraftInputSchema makes the user-facing copy (title, summary, service
label, client) optional; the action auto-generates a slug from the title
(or draft-<timestamp>), defaults the year to the current year, and forces
the project unpublished
- Drafts drop not-yet-valid sections/assets instead of failing the save
- Pass intent via a hidden field set on click so the server reliably sees it
- Tests: draft schema accepts empty copy a strict save rejects, and still
requires a slug and a valid year
- Remove the tab navigation, per-step sidebar, and Previous/Next buttons;
render Basics, Localized Content, Sections and Assets stacked on a single
scrollable page
- Drop the now-unused wizard step machinery (currentStep state, wizardSteps,
StepStateBadge, step stat card) and related imports
- Keep the same fields, validation, and save gating (Basics + Localized
Content required; sections/assets optional)
- CASE_STUDY -> Web: two columns, stacked full-width screenshots with a
browser frame plus a sticky project info panel
- GRID -> Print: mixed-size gallery grid for logos/posters/etc.
- STORY -> Editorial: full-bleed hero with title overlay, then alternating
text/media sections
- Add a prominent title/summary intro (was missing from the header)
- Use PortfolioCover for all media so empty projects show the branded
placeholder instead of broken images; gallery sections render even
before an image is uploaded
- Fix critical bug: TabsContent unmounted inactive panels, so the project
form only submitted the active tab's fields and could never save; add an
opt-in forceMount that keeps panels mounted (hidden) and use it on all
four project-form tabs
- Make Sections and Assets optional: a project saves with just Basics and
Localized Content; new projects start with no sections/assets, and the
last one can now be removed
- Update wizard progress so empty sections/assets steps count as complete
- Update save hint copy and step labels to reflect the optional steps
- Correct .claude/launch.json dev port to 3014
- Update portfolio-form-progress tests for the optional-steps behaviour
Reduce the "interchangeable cards" monotony flagged in Phase 0 and apply the
warm-premium type scale.
- SectionHeading: use the type scale (eyebrow via .eyebrow with brand tint,
text-h2 title, body-lg description). Propagates to every home section.
- CapabilitiesSection: cleaner cards with a brand-tinted icon tile, type-scale
title/body, soft elevation (drops the AppCard wrapper).
- ProcessSection: reworked into an editorial numbered timeline (large
translucent brand numerals, top rule, no boxes) so it no longer looks
identical to Capabilities.
Verified: eslint clean, no new type errors, tailwind generates the utilities.
The homepage hero had no call to action (Phase 0 finding). Add a live
availability pill and primary/secondary CTAs while keeping the signature title.
- HomeHero: optional availability status pill (pulsing dot) plus primary
(view work) and secondary (contact) CTAs, RTL-aware arrow, using the type
scale. Backward compatible (all new props optional).
- Wire copy + hrefs from the homepage; add heroVisual.primaryCta /
secondaryCta to en/de/ar.
Verified: JSON valid, eslint clean, no new type errors.
The detail page rendered an empty <PageHero /> (blank gradient band) with the
real title buried in a card lower down (Phase 0 finding).
- Populate the detail PageHero with the project category (badge), title and
summary, so the top of the page is a proper header.
- Slim the in-content ProjectHeader to back-link + meta chips + preview button,
removing the now-duplicated title and summary. Applies across all three
detail templates (grid/story/case-study).
Verified: eslint clean, no new type errors.
Bring imagery to the homepage projects block (Phase 3), matching the portfolio
gallery.
- Thread coverImagePath through ProjectCardCopy and the home mapping.
- Rewrite ProjectsSection as image-first cards (reusing PortfolioCover with the
branded placeholder fallback): whole-card link, featured project spans two
columns with a larger cover, type-scale title, meta + stack badges, hover
lift. Replaces the previous text-only cards.
Verified: eslint clean; no new type errors (pre-existing Prisma-gen anys only).
Redesign the portfolio list/category grid into a premium, image-first gallery
(Phase 3), applying the warm-premium tokens.
- Add components/site/portfolio-cover.tsx: renders the stored cover image
(next/image, object-cover, hover zoom) or a restrained branded placeholder
(monogram + category) when none is set. Placeholders are temporary — the
owner will swap in real artwork.
- Rewrite portfolio-project-grid: responsive 1/2/3-col gallery, featured
projects span two columns with a larger cover, cards use the type scale
(text-h2/h3/caption), eyebrow category labels, line-clamped summaries, soft
elevation and hover lift. Directly fixes the "portfolio shows no images"
gap on the list and category pages.
Verified: eslint clean, no new type errors, tailwind generates the utilities.
Full refactor of the maintenance/coming-soon page for all locales (de/en/ar,
RTL-aware) with a refined, theme-aware (light + dark) premium composition:
glass panel, live status indicator, hero title, description, launch countdown
and CTAs. Reuses the existing hero/motion system; no new dependencies.
- Add components/site/launch-countdown.tsx: hydration-safe client countdown
(days/hours/minutes/seconds), localized labels, Arabic-aware typography,
"launched" fallback when the target passes.
- Rewrite app/[locale]/coming-soon/page.tsx around the countdown and a single
easy-to-edit LAUNCH_DATE_ISO constant (default ~45 days out).
- Add comingSoon i18n keys (status, countdownLabel, unit labels, launched)
to en/de/ar.
- Replace animated blob/wave/noise backdrop with clean static gradient
(radial ellipse highlights + linear fade) in hero-motion-backdrop
- Remove all framer-motion from background layer; delete unused CSS
classes: hero-blob, hero-sheet-glow, hero-sheet-wave, hero-sheet-noise,
hero-title-shift keyframe, and responsive blob media queries
- Add framer-motion stagger entrance to HeroContentMotion, HeroMotionItem,
and HeroTitle (slide-up + fade on mount)
- Refactor coming-soon page to use HeroContentMotion/HeroMotionItem
instead of MotionFade (whileInView unreliable above the fold)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>