Commit Graph
179 Commits
Author SHA1 Message Date
MOH 10600b48c4 WIP - save all current changes 2026-09-20 20:04:48 +02:00
moh a628b69133 FIXED - Move page transition from template to persistent layout so it animates
CI / quality (push) Canceled after 0s
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.
2026-09-20 19:55:13 +02:00
moh 4df0d9ae86 IMPROVED - Add page exit animation via frozen-router AnimatePresence
CI / quality (push) Canceled after 0s
Wrap the template in AnimatePresence (mode="wait") with a FrozenRouter that
pins the layout-router context, so the outgoing page animates out (blur +
rise) before the incoming page animates in.
2026-09-20 19:50:46 +02:00
moh 5c10bce740 IMPROVED - Replace per-title hero entrance with a unified page transition
- Add (site)/template.tsx: one framer-motion enter animation (fade + rise +
  blur) that runs on every navigation, so moving between dock pages has a
  clean transition.
- Disable the staggered .hero-rise entrance now that the template handles it.
2026-09-20 19:46:58 +02:00
moh 572329097c REMOVED - Drop Home dock item since the logo already links home
CI / quality (push) Canceled after 0s
2026-09-20 19:42:56 +02:00
moh 4017ba3b72 POLISHED - Soften dock hover magnification and enlarge tooltip text 2026-09-20 19:40:02 +02:00
moh 70203732d2 REVERTED - Restore corner radial controls; make dock icons full-bleed
- 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.
2026-09-20 19:37:17 +02:00
moh a6be3c26d2 IMPROVED - Collapse dock controls into one settings tile that fans out in an arc 2026-09-20 19:34:57 +02:00
moh 008cfcc515 IMPROVED - Move theme/sound/language controls into the dock after a separator
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.
2026-09-20 19:19:45 +02:00
moh e1030b7f3e IMPROVED - Fan the corner controls out along a radial arc 2026-09-20 19:15:57 +02:00
moh ac8746a287 IMPROVED - Use swappable image icons and move controls to a corner dock
- 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.
2026-09-20 19:12:44 +02:00
moh 6e7cc4dbc6 IMPROVED - Add custom macOS-style squircle app icons to the dock 2026-09-20 19:05:29 +02:00
moh 6543ccada3 IMPROVED - Fix dock bar height jump, enlarge icons, refine active state 2026-09-20 19:01:42 +02:00
moh 6c213699a2 ADDED - Replace site header menu with macOS menu bar and Magic UI dock
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.
2026-09-20 18:56:46 +02:00
moh f627118b2c CONFIGURED - Auto-activate git hooks via npm prepare script
Add a prepare script that runs 'git config core.hooksPath .githooks' on every
npm install, so the commit-msg style gate and pre-push test gate turn on
automatically per clone with nothing to remember. Guarded with '|| true' so
installs never fail where git is absent (e.g. tarball deploys). Document that
the deploy server never needs it since it only pulls.
2026-09-20 18:54:55 +02:00
moh 213c45476c CONFIGURED - Enforce VERB-style commit subjects via commit-msg hook
Add a commit-msg git hook that rejects any subject not matching
"VERB - Description" (ALL-CAPS verb + " - " + description), letting
merge/revert/fixup commits through. Document the mandatory style and the
no-attribution rule in CLAUDE.md, and note that .githooks is activated per
clone with core.hooksPath. Prevents the prefix-less commits agents kept
producing.
2026-09-20 18:53:48 +02:00
moh 3f96abc60f REFACTORED - Flatten portfolio category routes to /portfolio/[slug]
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.
2026-09-20 18:53:48 +02:00
moh 5b019052b1 STYLED - Add CSS hero entrance, title halo, and scroll cue
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.
2026-09-20 18:53:48 +02:00
moh bb9f1a2f6e STYLED - Add a layered ambient backdrop behind all heroes
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.
2026-09-20 18:53:48 +02:00
moh 369c0e24c6 STYLED - Turn the project form into a step-by-step wizard journey
CI / quality (push) Canceled after 0s
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.
2026-09-20 18:17:40 +02:00
moh d4b7f883e1 STYLED - Drop section cards in the project form, lay content flat on the page
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.
2026-09-20 18:01:03 +02:00
moh 19e8fa8f19 STYLED - Two-column project form, drop the redundant header card
- 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.
2026-09-20 17:40:45 +02:00
moh 077e1c5836 STYLED - Flatten media picker and use a two-column media layout
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.
2026-09-20 17:30:44 +02:00
moh 2f8fd66812 STYLED - Simplify and compact the add-project form
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.
2026-09-20 17:16:52 +02:00
moh 40387c19d4 STYLED - Turn the admin portfolio overview into a professional table
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.
2026-09-20 17:08:20 +02:00
moh d1245204f1 STYLED - Roll out the layered card system to the admin workspace
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.
2026-09-20 17:01:20 +02:00
moh 4b535694bc ADDED - Save an unfinished project as a draft
- 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
2026-09-20 16:52:13 +02:00
moh 39e459fa09 REVERTED - Drop body suppressHydrationWarning
- The hydration warning came from a browser extension, not the app; handling
  it at the extension level instead of masking it in the layout
2026-09-20 16:44:03 +02:00
moh 80b1365ebc FIXED - Suppress body hydration warning from browser extensions
- Browser extensions (e.g. ColorZilla's cz-shortcut-listen) inject attributes
  on <body> before React hydrates, causing a benign hydration mismatch warning
- Add suppressHydrationWarning to <body>, matching the existing <html>
2026-09-20 16:42:58 +02:00
moh 3c2421fb8b STYLED - Convert the add-project form from a 4-tab wizard to one page
- 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)
2026-09-20 16:39:59 +02:00
moh 22cd3f8645 STYLED - Rework project detail into three real layouts per viewMode
- 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
2026-09-20 16:27:05 +02:00
moh 26969e25b2 FIXED - Load .env in drizzle.config so drizzle-kit targets the right DB
- drizzle-kit does not read .env like the Next.js app, so DATABASE_URL was
  undefined and fell back to the default host, causing migrate to hang and
  push to fail against the wrong database
- Load .env via native process.loadEnvFile for local dev, guarded so
  production (env already set, no .env file) is unaffected
2026-09-20 02:05:54 +02:00
moh d78450fc47 FIXED - Make adding a portfolio project simpler and actually saveable
- 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
2026-09-20 01:56:50 +02:00
moh a13e33edcd DOCUMENTED - Sync agent docs with the real stack
CI / quality (push) Canceled after 0s
- Replace stale Prisma commands/paths in CLAUDE.md with Drizzle (db:generate/migrate/push/studio, lib/db/index.ts, lib/db/schema.ts)
- Fix Docker/Makefile command block to match actual make targets
- Correct middleware.ts references to proxy.ts (Next.js 16 entry point)
- Rename ' AGENTS.md' (leading space) to AGENTS.md so agent tooling can find it
- Remove stray characters from the AGENTS.md documentation-updates list
2026-09-20 01:26:12 +02:00
Moh 3a5c275c52 CLEANED - Remove unused comingSoon translation keys
CI / quality (push) Canceled after 0s
- Drop badge, kicker, status, primaryCta, secondaryCta, countdownLabel from all locales
- These were orphaned when the coming-soon page was trimmed to title + countdown
2026-08-08 03:52:08 +02:00
Moh b2b90bd1bf STYLED - Trim coming-soon to title + countdown
CI / quality (push) Canceled after 0s
- Remove the status badge, kicker, and description texts
- Keep only the title and the countdown (all locales)
2026-08-08 03:48:19 +02:00
Moh aadc93e870 STYLED - Simplify closed coming-soon page
CI / quality (push) Canceled after 0s
- Remove CTA buttons (site is closed, no navigation)
- Drop the card wrapper: content sits on the page background, gradient included
- Remove the launch label; keep the countdown
- Fit the viewport (no scroll)
2026-08-08 03:34:02 +02:00
Moh 0f436ec05a FIXED - Drop leftover Prisma ?schema=public from the DB URL
CI / quality (push) Canceled after 0s
- postgres.js forwarded schema as a startup param; Postgres rejected the connection
- Remove ?schema=public from docker-compose, CI, and the client default
- Strip any query string in lib/db/index.ts so this cannot recur
2026-08-08 03:04:26 +02:00
Moh 1264b577a1 FIXED - Restore the tested package-lock.json
CI / quality (push) Canceled after 0s
- Revert an unintended lockfile change from a machine with a newer npm
- Keeps the exact dependency tree the test suite ran against (npm ci verified)
2026-08-08 02:34:37 +02:00
Moh 61a58b31a7 CONFIGURED - Wire docker-compose to Traefik for first deploy
CI / quality (push) Canceled after 0s
- Join the app to the external proxy network and drop the published host port
- Add Traefik labels for mohfarawati.de, www, and root.mohfarawati.de
- Parametrize network/entrypoint/certresolver via TRAEFIK_* env with sane defaults
- Pass ADMIN_HOST to the app and document production env in .env.example
2026-08-08 02:33:09 +02:00
MOH cdf0380f79 IMPROVED - unify dev pattern: DB-only Docker + host app, safe start, add test:watch
CI / quality (push) Canceled after 0s
2026-08-07 15:05:34 +02:00
MOH 0a5f77d8de REFACTORED - migrate the data layer from Prisma to Drizzle (unify the stack)
- Add lib/db (Drizzle schema: 7 tables + 6 enums + relations, postgres.js client),
  drizzle.config.ts, lib/db/enums.ts (Prisma-compatible enum objects)
- Rewrite all 14 app consumers + 4 admin components to Drizzle
- Move the test DB layer to Drizzle + in-process PGlite; convert all 8 integration
  test files + factories (371 tests green)
- Remove Prisma: deps, prisma/ schema+migrations, lib/prisma.ts, Dockerfile prisma
  generate; wire db:generate/migrate/push/studio to drizzle-kit; update Makefile
- Preserve the old seed as scripts/legacy-prisma-seed.cjs (needs a Drizzle rewrite)
2026-08-07 14:18:41 +02:00
MOH e377877e7e ADDED - test gate: pre-push hook, copy-paste summary, make targets, mandatory-tests rule, CI test step 2026-08-06 20:03:37 +02:00
MOH 9c40d9030f FIXED - build type errors (vitest fileParallelism placement, NODE_ENV assignment) 2026-08-06 20:03:27 +02:00
MOH 777dcbab7b update 2026-08-06 02:27:49 +02:00
Moh e2e06be86e test: add comprehensive automated test coverage
- Vitest multi-project setup (unit / integration / component)
- Real-Postgres integration harness via in-process PGlite (TEST_DATABASE_URL
  override), migrations applied per worker; production code untouched
- Unit: routing, locale, validation/Zod schemas, metadata, mail, site-theme,
  marquee, media, portfolio helpers, plus architecture-rule tests
- Integration: Prisma data layer, API routes, and all server actions
- Component: UI primitives and form components (jsdom + Testing Library)
- 371 tests passing
2026-08-06 02:27:20 +02:00
MohFarawati 0f48381894 refactor(home): align contact CTA typography to the type scale
CI / quality (push) Has been cancelled
Use the eyebrow/.text-h2/body-lg tokens and caption/small labels so the
contact CTA matches the unified section styling. No structural change.
2026-07-14 22:38:08 +02:00
MohFarawati 59094eba85 refactor(home): unify section headings, differentiate capabilities and process
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.
2026-07-14 22:37:09 +02:00
MohFarawati dd72f013d4 feat(home): hero availability status and CTAs
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.
2026-07-14 22:23:54 +02:00
MohFarawati 86243b79c2 feat(portfolio): real project-detail hero, no wasted space
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.
2026-07-14 22:20:47 +02:00