Skip to content

feat: redesign website to match new corporate design#34

Merged
jhb-dev merged 36 commits into
mainfrom
may-2026-redesign
May 3, 2026
Merged

feat: redesign website to match new corporate design#34
jhb-dev merged 36 commits into
mainfrom
may-2026-redesign

Conversation

@jhb-dev
Copy link
Copy Markdown
Contributor

@jhb-dev jhb-dev commented May 3, 2026

No description provided.

jhb-dev and others added 30 commits May 2, 2026 23:48
- Sticky header with scroll-collapse past 80px (wordmark fades, mark stays)

- New nav with orange backslash hover/active indicator

- DE \ EN switcher with orange separator

- Cobalt-900 footer with orange top border, corner crosses, mono headings

- New mark: cobalt square with small orange backslash glyph (no tile/lego feel)

- Link component split into primary/ghost/text styles per §8.1/§8.2

- Add --container-page token for max-w-page utility
…n system

- HeroSection: paper-pure surface, masked grid, 4 corner crosses, cobalt-900 H1

- Section: \\ NN / TITLE eyebrow + smaller subtitle (was way too big for the layout)

- ServicesBlock: bento (1 hero + 2 compact) per §7.5, frame pattern, schematic SVG visualizations

- Drop Mehr erfahren copy in cards (per §11.11), arrow-only affordance

- Tweak logo backslash angle to ~67° to match Geist Mono glyph

- New primitives: Eyebrow, SectionFrame, FrameCell, ServiceVisual

- Add §12.11 (CMS overrides allowed during redesign) to redesign.md
…onials

- PhilosophyBlock: 4-column value bento with frame pattern (§7.6)

- AboutBlock: hairline-framed image, eyebrow + name heading, drop shadow

- CustomerLogosBlock: simple grid, hairline top/bottom border, drop horizontal scroll

- TestimonialsBlock: section frame with cells, sm-screen 2-up / lg 3-up grid

- TestimonialCard: figure/blockquote/figcaption with hairline divider, no card chrome
Bumps populated testimonial query to depth 3 so customer.logo resolves to an Image, not just an id.
…mage

- Testimonial cards: pin author/customer header to top so it stays visible in the collapsed state, drop the customer logo (too small to read)

- Switch to CSS columns masonry so uneven testimonial lengths flow without dead whitespace

- AboutBlock: container holds the aspect-square; image stretches with h-full w-full object-cover so portrait files always fill the box
- Header primary button: !px-4 !py-2 to reduce height in the lockup, mx-3 around the li for breathing room from neighboring nav items

- Section.astro: subtitle override map keyed by section title; Über JHB Software now reads 'zukunftsorientierte Individualsoftware, um Dein Unternehmen voranzubringen' instead of the long CMS sentence (TODO(cms-content) to write back)
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Actions Updated (UTC)
website Ignored Ignored May 3, 2026 4:59pm
website-cms Ignored Ignored May 3, 2026 4:59pm

Request Review

@claude
Copy link
Copy Markdown

claude Bot commented May 3, 2026

Code Review: feat: redesign website to match new corporate design

This is a large, well-structured redesign PR. Overall quality is high — the changes are coherent, the design system is clearly documented, and conventions are consistently applied. Here are the specific findings:


Potential Bugs

1. ServicesBlockisHero layout relies on exactly 1 hero + 2 others
The bento grid layout is built around having exactly 1 hero card and 2 non-hero cards. If content editors mark 0 or 2+ services as isHero, the grid layout will break visually (misaligned cells or empty columns). Consider adding a CMS validation or a defensive fallback in the Astro template.

2. PhilosophyBlocktitle made optional without defensive rendering
title was changed from required: true to required: false. If the Astro block template renders the title unconditionally (e.g., inside an <h2> with no null check), it may render an empty heading. Verify the template handles the title?: string | null case gracefully.

3. CodeBlock.astro — hardcoded language: 'ts'
There's a TODO noting the language field isn't exposed in the CMS yet, so syntax highlighting is hardcoded to TypeScript. This is fine as a known gap, but it will silently highlight non-TS code blocks incorrectly. Worth tracking in the roadmap.

4. Footer watermark — no pointermove cleanup on navigation
The watermark glow is registered via document.addEventListener('pointermove', ...). The script includes a document.addEventListener('astro:before-swap', ...) teardown, which is good. Just confirm the teardown also cleans up the requestAnimationFrame handle (i.e., cancelAnimationFrame is called) to avoid a dangling RAF loop after client-side navigation.


Performance

Marquee animation — duplicated DOM is correct pattern
The customer logos marquee duplicates each row in the DOM for the seamless loop. This is standard and correct — no issue.

Watermark RAF on pointermove
Each pointermove queues a new requestAnimationFrame. If the user moves the mouse quickly, multiple RAF callbacks can queue up before the next frame. Consider using a dirty flag (set on pointermove, clear after RAF fires) to coalesce updates to one frame. Low impact on modern hardware but worth noting.

Font strategy is good
font-display: swap and self-hosted WOFF2 files (Geist-Variable.woff2, GeistMono-Variable.woff2) are the right approach — no layout shift issues expected.


Security

No significant concerns. Specific checks:

  • All external links use rel="noopener noreferrer"
  • Inline SVGs are fully static (no dynamic content injected) ✓
  • RichText content is serialized by Payload CMS before rendering ✓
  • Icon names are a typed string union with unknown-case validation ✓
  • No set:html usage on untrusted content detected ✓

Style & Convention

Unused import in Layout.astro
CacheClearButton and its showCacheButton variable are commented out but still present. These can be removed.

ServicesBlockvisualization rename is clean
Old icon field is properly removed and replaced with visualization with updated enum values (mobile | web | webapp). The types in payload-types.ts are regenerated to match — good.

design.md is a great addition
Having an explicit design spec in the repo (colors, type scale, component rules) is exactly the right call for a team project. Aligns with the instruction in CLAUDE.md to keep area-specific conventions documented.

Tailwind v4 @theme usage is correct throughout
Color tokens, animations, and easing all defined in the @theme block rather than tailwind.config.js — consistent with v4 conventions.


Summary

Area Status
Bugs 1 medium (bento layout guard), 1 low (optional title rendering), 1 known gap (CodeBlock lang), 1 minor (RAF cleanup)
Performance No blockers; 1 minor optimization opportunity (watermark RAF coalescing)
Security Clean — no issues found
Style/Conventions Excellent; 1 minor cleanup (unused import)

The overall structure and quality of this PR is solid. The main actionable items before merge are:

  1. Add a guard in ServicesBlock.astro for the isHero count assumption
  2. Verify PhilosophyBlock.astro handles title: null without rendering an empty <h2>
  3. Confirm watermark RAF is cancelled on astro:before-swap

🤖 Generated with Claude Code

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 3, 2026

Preview Deployment

Project URL
CMS https://website-lszb0wlab-jhb-software.vercel.app
Web https://website-57fosrg0h-jhb-software.vercel.app

The Web preview uses the CMS preview URL for content fetching.

@claude
Copy link
Copy Markdown

claude Bot commented May 3, 2026

Code Review: feat/redesign-website (#34)

This is a substantial redesign PR (2795 additions, 884 deletions) covering the full corporate identity update — new design system, typography, icon system, layout components, and CMS schema changes. Overall the implementation is well-structured and follows project conventions. Below are my findings.


Overview

  • New design system: Geist font family, hairline frames (no shadows/gradients), CornerMark + Eyebrow + FrameCell layout primitives
  • CMS schema changes: ServicesBlock.iconvisualization + eyebrow + isHero, new Labels sections (footer, authors, projects, articles), PhilosophyBlock.title made optional
  • Redesigned components: Header, Footer, all card types, most block components
  • Icon system migrated from FontAwesome/Lucide → Geist icons (stroke-based, currentColor)

Potential Bugs / Issues

1. ServicesBlock field rename (iconvisualization) — HIGH
The old icon field is completely replaced. Any CMS content that was saved with the old icon field will lose its value since Payload won't auto-migrate it. Existing records need a migration or manual re-entry.

2. Tailwind custom classes not verified
New utility classes (tracking-eyebrow, tracking-wordmark, max-w-page) are used across multiple components but tailwind.config.ts is not in the diff. If these aren't defined there, the classes will silently produce no output.

3. PhilosophyBlock.title changed to optional without a fallback
PhilosophyBlock.astro may not handle null gracefully if the heading is conditionally rendered. Worth verifying the component guards against a missing title ({title && <h2>...</h2>} pattern).

4. Duplicated logo SVG in Header
The brand logo SVG is duplicated between the main nav and the mobile modal. Minor, but if the logo changes again both copies need updating. Consider extracting to a shared component.

5. TestimonialsBlock depth increase (2 → 3)
The depth increase to resolve customer.logo is justified, but it will increase payload response size for every page that includes a testimonials block. Fine for now given typical data volumes, but worth documenting.


Performance Considerations

  • Font loading: Two new variable fonts (Geist-Variable.woff2, GeistMono-Variable.woff2) are added. Ensure these are <link rel="preload"> in the document head to avoid layout shift / FOIT.
  • CustomerLogosBlock marquee: DOM nodes are doubled for the seamless loop (each logo rendered twice). Acceptable for typical logo counts but worth keeping in mind.
  • Footer watermark pointer tracking: Uses requestAnimationFrame correctly — no concerns.
  • IntersectionObserver for header collapse: Solid pattern, better than a scroll listener.

Security

  • All new target="_blank" links include rel="noopener noreferrer" — correct.
  • CMS-sourced strings (labels, eyebrow text) are rendered as text content, not set:html — no XSS surface.
  • No new security concerns introduced.

Code Quality

  • New layout primitives (CornerMark, Eyebrow, FrameCell) are well-named, follow PascalCase Astro conventions, and include clear prop comments — good.
  • astro:page-load / astro:before-swap lifecycle hooks are used correctly for header menu setup/teardown, with no memory leaks detected.
  • The card component prop signature change (featured?: booleanvariant?: 'featured' | 'compact') is cleaner and more extensible.
  • design.md and roadmap.md added to repo root — consider whether these belong in the repo or in a Notion/wiki. At minimum, roadmap.md feels more like living documentation than committed code.

Checklist Reminders (per CLAUDE.md)

  • pnpm lint, pnpm check, pnpm format run in /web?
  • pnpm lint, pnpm format run in /cms?
  • pnpm generate:types run in /cms after schema changes? (ServicesBlock + Labels changed — types must be regenerated and committed)

The payload-types.ts diff looks like it was updated, but please confirm pnpm generate:types was the source of truth and not a manual edit.


Summary

The redesign is coherent and well-executed. The main action items before merging are:

  1. Confirm Tailwind config includes the new custom utilities
  2. Plan a CMS data migration for the iconvisualization rename in ServicesBlock
  3. Add font preload hints
  4. Verify PhilosophyBlock.astro handles null title gracefully
  5. Run all lint/format/type-gen commands per CLAUDE.md conventions

@claude
Copy link
Copy Markdown

claude Bot commented May 3, 2026

Code Review: feat: redesign website to match new corporate design

Overall this is a well-structured redesign. The new design primitives (SectionFrame, FrameCell, CornerMark, Eyebrow, Heading) are composable and consistent, security posture is solid, and the font/token strategy is coherent. A few items need attention before merge.


🔴 Bugs / Breaking Changes

1. ServicesBlock schema is a breaking content migration
icon (select) is removed and replaced with eyebrow (required text) + visualization (select). Existing CMS entries will have neither field populated after this deploy. Since eyebrow is required: true, Payload will not enforce this on existing data at the DB level — but the frontend will render an empty/undefined eyebrow label silently. Content editors need to backfill every service entry manually before or immediately after deploy.

2. ServiceVisual has no fallback for unknown visualization values
If a value comes through that isn't 'mobile' | 'web' | 'webapp', the component renders nothing (no fallback SVG, no error). Given the schema also accepts no value during a data migration window, this could result in a blank service card visual with no indication of the problem.

// Consider adding a fallback:
{visualization === 'mobile' && <MobileVisual />}
{visualization === 'web' && <WebVisual />}
{visualization === 'webapp' && <WebAppVisual />}
{!visualization && <div class="..." aria-hidden="true" />}  {/* graceful empty state */}

3. prose-redesign Tailwind class is referenced but not visible in the diff
Several components use prose-redesign (a custom Tailwind utility). If this class is not defined in tailwind.config.*, prose content across article/project pages will silently lose all styling. Please confirm it is present in the config.


🟡 Performance Considerations

4. CustomerLogosBlock duplicates the full logo list in the DOM for the marquee
The marquee effect works by rendering the logo list twice side-by-side. For ~12 logos this is fine, but if the list grows the DOM duplication and continuous CSS animation will increase paint cost. Consider using will-change: transform on the animation container and capping the list length in the CMS schema if this block is used on the homepage above the fold.

5. Footer watermark pointer-tracking recalculates a radial gradient on every pointermove
The requestAnimationFrame guard is good, but getComputedStyle is called each frame. Reading --header-h once on mount (and on resize) and caching it would be slightly cheaper. This is low priority but worth noting for future optimization.


🟡 Minor Issues

6. PhilosophyBlock.title is now optional in the schema but rendering may not guard against null
The field was changed from required: truerequired: false. Confirm the PhilosophyBlock Astro component handles title === null | undefined gracefully (e.g., skip the heading element rather than rendering an empty <h2>).

7. Section eyebrow index numbering
The index prop for section numbering starts at 2 (hero is implicit 1). If a page has no hero section or sections are conditionally rendered, the numbering sequence will have gaps. This is cosmetic but could look odd — worth validating against all page templates.

8. Hardcoded SUPPORTED_SOCIAL_ICONS in AuthorLayout
The footer social icon registry is open/dynamic, but AuthorLayout filters against a hardcoded array. Adding a new social platform to the CMS won't automatically show up on author pages without a code change. Consider sharing a single source of truth.


✅ What looks good

  • All target="_blank" links include rel="noopener noreferrer"
  • loading="lazy" on below-fold images; fetchpriority="high" on featured images ✓
  • No unsanitized HTML rendering — all CMS content is rendered as text or through the safe RichText component ✓
  • SVGs are aria-hidden="true" and focusable="false"
  • prefers-reduced-motion respected in the watermark animation ✓
  • Payload types regenerated correctly (pnpm generate:types was run) ✓

Pre-merge checklist

  • Backfill plan for existing ServicesBlock content (eyebrow + visualization fields)
  • Confirm ServiceVisual renders a graceful fallback when visualization is undefined
  • Confirm prose-redesign utility is defined in Tailwind config
  • Confirm PhilosophyBlock Astro component guards against title === null

@claude
Copy link
Copy Markdown

claude Bot commented May 3, 2026

Code Review — feat: redesign website to match new corporate design

Overview

This is a substantial, well-scoped redesign. The new design system (design.md) is documented clearly, the token naming is role-based and coherent, and the new component abstractions (Eyebrow, Heading, SectionFrame, FrameCell, CornerMark, MetaStrip, MetaField) are clean and consistently applied. The header collapse/scroll logic, footer watermark interaction, and marquee animation are all implemented correctly with proper cleanup and prefers-reduced-motion guards.


Potential Bugs

1. building.svg and home.svg have identical SVG paths

building.svg was updated to:

<path d="M3 9l9-7 9 7v11a2 2 0 01-2 2H5a2 2 0 01-2-2z" />
<path d="M9 22V12h6v10" />

This is the same path as home.svg. The building icon is used in TestimonialCard.astro for customer website links — it should be a distinct building/office shape.

2. ServicesBlock.astro silently drops services in bento mode

{compactServices.slice(0, 2).map((service, idx) => (...))}

When useBento is true, any compact services beyond the first two are silently dropped. If an editor marks 3 compact services alongside a hero service, the third disappears with no warning. Worth either rendering the extras in a fallback row, or capping the CMS field to 2 in that context.

3. whatsapp.svg is now identical to comments.svg

The new WhatsApp SVG uses the generic message-bubble path (M21 15a2 2 0 01-2 2H7l-4 4V5...), which is the same path that comments.svg already uses. The two icons are now indistinguishable. WhatsApp's rounded-bubble shape is distinct enough to matter for social link recognition.

4. PhilosophyBlock title is now optional but the split-section logic passes '' as subtitle

In PageLayout.astro:

subTitle: 'title' in philosophy ? (philosophy.title ?? '') : '',

When philosophy.title is null/undefined, subTitle becomes ''. Section.astro guards with title || subTitle, so a falsy subTitle is silently omitted — harmless but may produce a heading-less eyebrow number if title also happens to be absent.


Performance

5. geist npm package unnecessarily pulls in Next.js

geist@1.7.0 declares next >=13.2.0 as a peer dependency, which causes the full next@16.2.2 snapshot (including all @next/swc-* platform binaries) to appear in pnpm-lock.yaml. The font files are already self-hosted at web/public/fonts/Geist-Variable.woff2 and loaded via @font-face in styles.css — the npm package is not needed at runtime. Removing geist from web/package.json while keeping only the woff2 files would eliminate this transitive dependency.

6. Testimonials query depth increased from 2 → 3

The added comment explains why (customer logo resolution chain: testimonial → project → customer → logo). Legitimate reason, but every page with a testimonials block now issues a deeper join. Worth monitoring on pages with large testimonial sets.


Code Quality

7. Commented-out code in Layout.astro

Both the CacheClearButton import and its usage site are commented out with // / {/* */} rather than removed. If the feature is gone, remove it; if it's coming back, a // TODO pointing to an issue is clearer than dead code.

8. Brand logo SVG duplicated in Header.astro

The inline <svg> for the JHB mark appears twice verbatim — once in the desktop header and once inside the mobile nav modal. A small BrandMark.astro component or an <img src="/icon.svg"> reference would avoid drift risk.

9. highlightBackground prop silently removed from Section.astro

The prop is dropped without a migration note. If any live CMS entries have this flag set it will silently have no effect — probably fine for a redesign, but worth a content audit note.


Security

No issues found. All external links use rel="noopener noreferrer". SVGs are inlined (no external references). No user-controlled input is rendered unsanitized.


Summary

The work is solid and the design language is well-executed. Most actionable before merge: the icon identity bug (#1 and #3), silent services truncation (#2), and the unnecessary Next.js transitive dependency (#5). The rest are low-risk cleanup.

@jhb-dev jhb-dev merged commit 9d7d226 into main May 3, 2026
11 of 12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant