# NEG AG Website — PRD & Handoff

Single source of truth: what this product is, what's built, and what a developer needs
to do to launch it. (Run/stack details are in the root `README.md`; deployment in
`DEPLOY.md`.)

**Status:** feature-complete, polished, on staging at `website.negag.cloud`.
**Last updated:** 2026-06.

---

## 1. Overview

NEG AG (Northgate Enterprises Group AG) is an established real-estate project developer
in Leipzig and Berlin. Its old WordPress site reads as dated and low-quality. This
project replaces it with a premium, self-managed marketing site backed by a headless CMS
(Sanity), so the team publishes projects and news without a developer.

The deliverable is the public site **plus** an embedded editor (Sanity Studio) the
client owns and operates.

## 2. Goals & success criteria

- Read as **solid, premium, calm** — a credible, established developer, never a template
  or "AI-generated."
- Route two audiences: **projects/references** (buyers, tenants) and **Ankauf/contact**
  (sellers, partners, investors).
- Non-technical editors manage content with no redeploy.
- Capture inbound leads into the CRM (Pipedrive).
- Production bar: responsive, accessible (WCAG AA intent), fast, SEO-ready,
  reduced-motion safe.

**Done =** the site fully replaces neg.ag (all pages + legal + working lead form),
content is editable in the Studio, and leads reach Pipedrive.

## 3. Audience

| Persona | Job on the site |
|---|---|
| Wohn-Interessenten & Mieter | Trust NEG as a credible builder; find projects. |
| Kapitalanleger / Partner | Read scale and track record fast. |
| Verkäufer (Ankauf) | Understand NEG buys property; reach the right contact. |

German-language, desktop + mobile, mostly first-time visitors in an evaluation mindset.

## 4. Scope — pages

`/` · `/projekte` (+ `/[slug]`) · `/referenzen` · `/unternehmen` · `/ankauf` ·
`/partner` · `/karriere` · `/soziales` · `/news` (+ `/[slug]`) · `/kontakt` ·
`/impressum` · `/datenschutz` · `/studio` (embedded editor).

Navigation: flat primary nav (Projekte · Referenzen · Ankauf · Unternehmen · Aktuelles) +
Kontakt CTA; secondary pages (Partner/Karriere/Soziales, legal) in the footer; mobile
hamburger menu.

## 5. Content model (Sanity)

Document types: `homePage`, `project`, `post`, `siteSettings`, `page`. Editors publish in
the Studio (`/studio`); pages are server-rendered so changes are live immediately. Live
preview / click-to-edit is wired via `next-sanity` `defineLive`.

> An `inquiry` type exists from the original form storage but is being retired — leads go
> to **Pipedrive**, not the CMS (see §11, NEG-1).

## 6. Functional requirements

- CMS-managed content for homepage, projects, references, news, team.
- **Contact form** (`/kontakt`): validates, honeypot anti-spam, sends the lead to
  **Pipedrive** with a fallback log (see §11).
- Project gallery: carousel + native `<dialog>` lightbox, keyboard nav, pausable
  autoplay.
- Embedded Studio with draft-mode preview.

## 7. Non-functional requirements

- Responsive mobile → desktop.
- Accessibility: semantic markup, focus states, ARIA on controls,
  `prefers-reduced-motion` honored everywhere.
- Performance: standalone server bundle; Sanity CDN images; transform/opacity motion.
- SEO: per-page metadata; legal pages `noindex` until finalized; 301s for old slugs.
- German language.

## 8. Design

Built from `src/app/neg.css` (the live design system, ported from the approved
prototype). Host Grotesk + Open Sans. Palette: Blau `#2B3A44`, Gold `#B8A387`, cream
`#FBF9F6`. Motifs: glass pill nav, cut-corner cards, wavy footer, gold-stripe dividers,
uppercase display headings. Tone: grounded, premium, unagitated. **Reuse the system; do
not invent new page designs.**

## 9. Architecture

Next.js 16 (App Router) + embedded Sanity Studio, Sanity cloud CMS, deployed as a Docker
standalone container behind Caddy on the client VPS. Stack and structure: `README.md`.
Deploy: `DEPLOY.md`.

## 10. Current status (what's built)

- **All 14 pages built** and on the shared design system; nav + mobile menu done.
- **Backend complete**: schema deployed, Studio configured (preview + structure), and
  populated — **15 projects, 4 posts, homepage, siteSettings** live in `production`.
- **Motion** audited and intentional; reveals are crawler/no-JS safe; reduced-motion
  fully supported.
- Verified throughout with `bunx tsc --noEmit` + `bun run build` (green) and
  desktop/mobile screenshots.

## 11. Remaining work — developer tasks

Do in this order. Verify every change with `bunx tsc --noEmit && bun run build`.

**NEG-1 · Contact form → Pipedrive (with fallback log)** *(P0)*
Leads go to **Pipedrive (CRM)**, not Sanity. Today `/kontakt`'s server action
(`src/app/kontakt/actions.ts`) writes a Sanity `inquiry` — replace it: add a Pipedrive
client (`PIPEDRIVE_API_TOKEN`), create a Person + Lead/Deal on submit (source = "Website
Kontaktformular"). **If Pipedrive fails, persist the lead to a fallback store** (a small
DB table recommended, or reuse the Sanity `inquiry` type as the fallback bucket) so no
lead is lost; return success only once the lead is safely stored. Keep honeypot +
validation. *Acceptance:* valid submit → lead in Pipedrive; with the token broken → same
submit lands in the fallback. Then the Sanity `inquiry` type can be removed.

**NEG-2 · Fix the homepage contact form** *(P0)*
The homepage form (`src/app/page.tsx`, `HomeScripts.tsx`) only fakes success — it never
submits. Either wire it to the NEG-1 flow or replace it with a CTA to `/kontakt`. No
dead form.

**NEG-3 · 301 redirects for old slugs** *(pre-launch)*
`next.config.ts` `redirects()`: `/news-presse` → `/news`, `/soziales-engagement` →
`/soziales` (+ any others from the old sitemap).

**NEG-4 · SEO foundation incl. local/geo** *(pre-launch)*
Add `src/app/sitemap.ts`, `robots.ts`, `metadataBase` + default Open Graph image +
`og:locale=de_DE` in `layout.tsx`. JSON-LD **`RealEstateAgent`** (a `LocalBusiness`
subtype) with: `PostalAddress` (Zimmerstraße 3, 04109 Leipzig, DE), `GeoCoordinates`
(geocode the office — verify exact lat/lng), phone, logo/url, and `areaServed`
(Leipzig, Berlin, Mitteldeutschland). None exist yet.
*Done when:* `/sitemap.xml` + `/robots.txt` resolve, OG preview renders, and the
structured data passes Google's Rich Results test with address + geo present.

**NEG-5 · Branded 404 / error pages** *(pre-launch)*
Add `src/app/not-found.tsx` + `error.tsx` using `SiteHeader`/`SiteFooter` + `neg.css`.

**NEG-6 · App icons** *(pre-launch)*
Add `src/app/icon.png` + `apple-icon.png` from the NEG logo (only `favicon.ico` exists).

**NEG-7 · Production deploy + verify** *(ship)*
Set runtime env on the server (`PIPEDRIVE_API_TOKEN`, `SANITY_API_READ_TOKEN`, fallback
creds), add the prod origin to Sanity CORS, deploy per `DEPLOY.md`. *Acceptance:* site +
`/studio` load; a real submit appears in Pipedrive; breaking the token routes it to the
fallback.

**NEG-8 · Launch QA** *(verify)*
Lighthouse ≥ 90 (perf/SEO/a11y), keyboard nav, reduced-motion, cross-browser + mobile.

**NEG-9 · Content completeness** *(ongoing, with client)*
Confirm each project has summary + KPIs + gallery; real posts published.

## 12. Blocked — needs client

- **Credentials:** Pipedrive API token (`PIPEDRIVE_API_TOKEN`) + a Sanity **Viewer** token
  (`SANITY_API_READ_TOKEN`, for live preview).
- **Legal text:** fill `/impressum` placeholders (HRB no., USt-IdNr., Aufsichtsrat) and
  the `/datenschutz` body (client/counsel), then remove `robots: { index: false }` from
  both. Cookie banner only if non-cookieless tracking is added (PostHog is cookieless).
- **Imagery:** real team headshots + a company/office hero image.

## 13. Out of scope (now)

Multi-language (German only), online transactions / listings search / accounts,
newsletter automation.
