From 6d32eb9b0e188ab5d3f511e8b029dc86f580183b Mon Sep 17 00:00:00 2001 From: CCS Admin Date: Sun, 15 Feb 2026 11:07:35 +0000 Subject: [PATCH] docs: add Definity design guidelines and update CLAUDE.md - docs/DESIGN.md: Full design system reference (colors, typography, spacing, shadows, components, animation patterns) - CLAUDE.md: Updated with design system summary, component library, implemented blocks (9/15), architecture overview Co-Authored-By: Claude Opus 4.6 --- CLAUDE.md | 170 +++++++++++++++++++++++++------------------------ docs/DESIGN.md | 90 ++++++++++++++++++++++++++ 2 files changed, 177 insertions(+), 83 deletions(-) create mode 100644 docs/DESIGN.md diff --git a/CLAUDE.md b/CLAUDE.md index 9a08105..ce44c71 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -4,12 +4,13 @@ This file provides guidance to Claude Code when working with this repository. ## Project Overview -porwoll.de frontend — a Next.js 16 application for professional portrait and business photography by Caroline Porwoll. Consumes Payload CMS as a headless backend. +porwoll.de frontend — a Next.js 16 application for Martin Porwoll (Whistleblower, Unternehmer, Mensch). Consumes Payload CMS as a headless backend. **Tenant:** porwoll (ID: 1, Slug: porwoll) **Tech Stack:** Next.js 16, React 19, TypeScript, Tailwind CSS 4 **Backend API:** https://cms.c2sgmbh.de/api **Package Manager:** pnpm +**Design System:** Definity Template (light, professional) ## Commands @@ -38,33 +39,57 @@ This project uses `@c2s/payload-contracts` for the API client and types. **Architecture:** - `src/lib/cms.ts` — Shared PayloadClient instance (tenant: porwoll, ID: 1) -- `src/lib/api.ts` — API functions powered by contracts client (types re-exported from contracts) +- `src/lib/api.ts` — API functions powered by contracts client **Contracts Repo:** `github:complexcaresolutions/payload-contracts` -```typescript -// CMS client (src/lib/cms.ts) -import { createPayloadClient } from "@c2s/payload-contracts/api-client" -export const cms = createPayloadClient({ - baseUrl: process.env.NEXT_PUBLIC_PAYLOAD_URL!, - tenantId: process.env.NEXT_PUBLIC_TENANT_ID!, -}) - -// Usage — tenant isolation is automatic -const page = await cms.pages.getPage("home") -const posts = await cms.posts.getPosts({ type: "blog" }) -``` - **Types:** Imported directly from `@c2s/payload-contracts/types`. No local type overrides. -**Block Catalog:** See `node_modules/@c2s/payload-contracts/docs/BLOCK_CATALOG.md` - **Updating Contracts:** ```bash pnpm update @c2s/payload-contracts pnpm build # Verify types still compile ``` +## Design System (Definity Template) + +Full guidelines: `docs/DESIGN.md` + +### Key Tokens + +| Token | Value | Usage | +|-------|-------|-------| +| `dark` | #111111 | Headings, dark backgrounds | +| `accent` | #2CAADF | Links, highlights | +| `gray` | #777777 | Body text | +| `light-bg` | #f4f4f4 | Section backgrounds | + +### Fonts + +- **Headings:** Montserrat Bold, UPPERCASE, letter-spacing 2-5px +- **Body:** Open Sans Light (300), 14px, letter-spacing 0.2px +- Loaded via `next/font/google` (CSS variables --font-montserrat, --font-open-sans) + +### Key Patterns + +- All headings are UPPERCASE with generous letter-spacing +- Cards: material shadow, hover lift (-10px translateY) +- Navigation: transparent-to-solid on scroll (100px threshold) +- Animations: framer-motion, viewport-triggered (once: true) +- Section padding: ws-s (50px), ws-m (100px), ws-l (160px) +- Tailwind v4: theme config in globals.css via @theme, no tailwind.config.ts + +### Component Library + +- `src/components/ui/Button.tsx` — 6 variants, 3 sizes +- `src/components/ui/Container.tsx` — 4 width options +- `src/components/ui/SectionHeader.tsx` — title + subtitle +- `src/components/Navigation.tsx` — fixed, transparent/solid +- `src/components/Footer.tsx` — social bar, widgets, copyright +- `src/lib/typography.ts` — heading classes, prose styles +- `src/lib/animations.ts` — framer-motion variants +- `src/lib/utils.ts` — cn() utility (clsx + tailwind-merge) + ## Architecture ### Directory Structure @@ -72,94 +97,73 @@ pnpm build # Verify types still compile ``` src/ ├── app/ -│ ├── layout.tsx # Root layout +│ ├── layout.tsx # Root layout (Montserrat + Open Sans) +│ ├── template.tsx # Page transitions (framer-motion) +│ ├── globals.css # Tailwind v4 @theme config │ ├── page.tsx # Homepage (CMS page: "home") │ └── [slug]/page.tsx # Dynamic CMS pages ├── components/ -│ └── blocks/ -│ └── index.tsx # Block renderer (placeholder components) +│ ├── Navigation.tsx # Transparent-to-solid nav +│ ├── Footer.tsx # Dark footer with widgets +│ ├── ui/ # Design system primitives +│ │ ├── Button.tsx +│ │ ├── Container.tsx +│ │ └── SectionHeader.tsx +│ └── blocks/ # CMS block components +│ ├── index.tsx # Block renderer +│ ├── HeroBlock.tsx +│ ├── TextBlock.tsx +│ ├── CardGridBlock.tsx +│ ├── QuoteBlock.tsx +│ ├── ImageTextBlock.tsx +│ ├── CTABlock.tsx +│ ├── ContactFormBlock.tsx +│ ├── TimelineBlock.tsx +│ └── DividerBlock.tsx └── lib/ ├── cms.ts # PayloadClient instance - └── api.ts # API functions + ├── api.ts # API functions + ├── utils.ts # cn() utility + ├── typography.ts # Typography class strings + └── animations.ts # framer-motion variants ``` ### Block System -Pages from Payload contain a `layout` array of blocks. The block renderer uses `createBlockRenderer()` from contracts. +Pages from Payload contain a `layout` array of blocks. The BlockRenderer maps `blockType` to components. -**Registered Blocks (~15):** +**Implemented Blocks (9):** -| Block Type | Status | -|------------|--------| -| `hero-block` | Placeholder | -| `text-block` | Placeholder | -| `image-text-block` | Placeholder | -| `card-grid-block` | Placeholder | -| `cta-block` | Placeholder | -| `divider-block` | Placeholder | -| `testimonials-block` | Placeholder | -| `faq-block` | Placeholder | -| `contact-form-block` | Placeholder | -| `image-slider-block` | Placeholder | -| `services-block` | Placeholder | -| `team-block` | Placeholder | -| `locations-block` | Placeholder | -| `stats-block` | Placeholder | -| `quote-block` | Placeholder | +| Block Type | Component | Key Features | +|------------|-----------|--------------| +| `hero-block` | HeroBlock | Full-screen, parallax, overlay, bounce arrow | +| `text-block` | TextBlock | Prose styling, 3 widths | +| `card-grid-block` | CardGridBlock | Material cards, hover lift, stagger | +| `quote-block` | QuoteBlock | Parallax or simple style | +| `image-text-block` | ImageTextBlock | 50/50 split, slide-in | +| `cta-block` | CTABlock | Fixed height, dark overlay | +| `contact-form-block` | ContactFormBlock | Underline inputs, card container | +| `timeline-block` | TimelineBlock | Alternating, vertical line | +| `divider-block` | DividerBlock | Line or whitespace | -**Implementing a block:** Replace the Placeholder in `src/components/blocks/index.tsx` with a real component. Use `BlockByType<"hero-block">` from contracts for type-safe props: - -```typescript -import type { BlockByType } from "@c2s/payload-contracts/types" - -type Props = Omit, "blockType"> - -export function HeroBlock({ headline, subline, backgroundImage }: Props) { - // Render block -} -``` +**Not yet implemented:** testimonials-block, faq-block, services-block, team-block, locations-block, stats-block, image-slider-block (render as dev-only placeholders). ### API Endpoints | Endpoint | Purpose | |----------|---------| -| `GET /api/pages?where[tenant][equals]=1` | Pages | -| `GET /api/posts?where[tenant][equals]=1` | Blog posts | -| `GET /api/navigations?where[tenant][equals]=1` | Navigation menus | -| `GET /api/site-settings?where[tenant][equals]=1` | Site configuration | -| `GET /api/testimonials?where[tenant][equals]=1` | Customer testimonials | -| `GET /api/bookings?where[tenant][equals]=1` | Photography bookings | +| `GET /api/pages` | Pages | +| `GET /api/posts` | Blog posts | +| `GET /api/navigations` | Navigation menus | +| `GET /api/site-settings` | Site configuration | +| `GET /api/social-links` | Social media links | +| `GET /api/testimonials` | Customer testimonials | +| `GET /api/bookings` | Photography bookings | | `POST /api/newsletter/subscribe` | Newsletter signup | | `POST /api/form-submissions` | Contact form | **API Documentation:** https://cms.c2sgmbh.de/api/docs -## Design Guidelines - -**Philosophy:** Professional, clean, hero-driven. Photography-focused — let the images speak. - -**Tone:** Serioes, warm but professional. German language (de). - -**Key Principles:** -- Large hero images that showcase photography work -- Clean whitespace, minimal visual clutter -- Professional typography (no playful fonts) -- Before/After comparisons for retouching work -- Portfolio galleries with lightbox -- Mobile-first responsive design - -**Photography Specialties:** -- Business portraits / Headshots -- Personal branding -- Team photography -- Event photography - -## porwoll-Specific Collections - -- **bookings** — Photography session bookings -- **services** — Photography packages offered -- **locations** — Studio/shooting locations - ## Git Workflow | Branch | Purpose | Deployment | diff --git a/docs/DESIGN.md b/docs/DESIGN.md new file mode 100644 index 0000000..8c27919 --- /dev/null +++ b/docs/DESIGN.md @@ -0,0 +1,90 @@ +# porwoll.de Design Guidelines - Definity Template + +## Design System Overview + +porwoll.de uses the **Definity Template** design system — a light, professional theme with clean typography, material card effects, and elegant animations. + +## Color Palette + +| Token | Hex | Usage | +|-------|-----|-------| +| dark | #111111 | Headings, primary text, dark backgrounds | +| gray | #777777 | Body text | +| gray-light | #999999 | Secondary text, labels | +| light | #ececec | Borders, dividers | +| light-soft | #f8f8f8 | Card backgrounds | +| light-bg | #f4f4f4 | Section backgrounds | +| accent | #2CAADF | Links, highlights, accent elements | +| accent-dark | #1a8fc4 | Accent hover state | +| error | #e80000 | Form errors | +| success | #0F9D58 | Success messages | + +## Typography + +| Element | Font | Weight | Size | Letter-Spacing | Transform | +|---------|------|--------|------|----------------|-----------| +| H1 | Montserrat | 700 | 1.7em | 5px | UPPERCASE | +| H2 | Montserrat | 700 | 1.5em | 4px | UPPERCASE | +| H3 | Montserrat | 700 | 1.3em | 3.5px | UPPERCASE | +| H4 | Montserrat | 700 | 1.07em | 3px | UPPERCASE | +| Body | Open Sans | 300 | 14px | 0.2px | normal | +| Label | Montserrat | 700 | 0.85em | 2px | UPPERCASE | +| Button | Montserrat | 700 | 0.9em | 2.5px | UPPERCASE | +| Nav Link | Montserrat | 400 | 0.8em | 2px | UPPERCASE | + +Key principle: All headings UPPERCASE with letter-spacing. Body text light-weight (300). + +## Spacing + +| Token | Value | Usage | +|-------|-------|-------| +| ws-s | 50px | Small section padding | +| ws-m | 100px | Standard section padding | +| ws-l | 160px | Large section padding | + +## Shadows + +| Token | Value | Usage | +|-------|-------|-------| +| card | 0 1px 1px rgba(0,0,0,0.2) | Card resting state | +| card-hover | 0 22px 43px rgba(0,0,0,0.15) | Card hover lift | + +## Components + +### Button (6 variants) +- default: Dark fill, light text +- ghost: Transparent, dark border, fills on hover +- ghost-light: Transparent, white border (dark backgrounds) +- light: Light fill, dark text +- text: No border, underline on hover +- text-light: Same, for dark backgrounds +- 3 sizes: small, default, large. Optional rounded prop. + +### Card (Material Style) +- White bg, light border, subtle resting shadow +- Hover: -10px translateY + deep shadow +- Padding: 50px/40px + +### Navigation +- Fixed, transparent on hero pages, solid on scroll (100px threshold) +- Shrinks 75px to 50px height +- Dropdown: slide-in with left border accent + +### Footer +- Social links bar (horizontal, pipe-separated) +- Dark 4-column grid (About, Nav, Legal, Contact) +- Copyright bar (#222) + +## Animation Patterns (framer-motion) + +- fadeInUp: opacity 0-1, y 30-0 +- slideIn: x 30-0 (image-text blocks) +- stagger: 0.1s delay between children +- cardHover: y 0 to -10, shadow transition +- Page transitions: opacity fade via template.tsx +- viewport trigger: once: true + +## CSS Architecture (Tailwind v4) + +Theme tokens in globals.css via @theme {} directive. +No tailwind.config.ts. Font variables from next/font/google.