Roman-inspired redesign with terracotta palette and Cinzel headings - #31
Roman-inspired redesign with terracotta palette and Cinzel headings#31TomSeestern wants to merge 1 commit into
Conversation
…dings (#30) * style: roman-inspired redesign with terracotta palette and Cinzel headings Transform the portfolio visual identity from modern blue/Inter to a warm Roman-inspired theme. The semantic token architecture means most changes cascade from tailwind.config.js — components reference semantic tokens rather than raw colors, so updating token values repaints the site. Palette: terracotta (#C2410C) primary replacing blue, warm marble whites for surfaces, warm charcoal text. Gold/amber accents preserved via accent hierarchy. Dark mode parity maintained — every semantic token has a -dark variant. Typography: Cinzel (classical serif) for h1-h4 via CSS variable --font-heading applied in layout. Inter retained for body text readability. Scope: - tailwind.config.js: new primary scale, recolored semantic tokens, added fontFamily.heading token, prose config auto-updates via theme() refs. - app/layout.tsx: load Cinzel alongside Inter, expose --font-heading variable, apply via <style> to all headings. - components/Tooltip: replace neutral-700 with surface-dark for warm dark-theme consistency, swap font-open-sans for font-body. - app/contact/page.tsx: strip undefined dark:shadow-sm-light variant that was silently dropped by Tailwind JIT. Verification: - pnpm lint, prettier, build, test all pass - WCAG AA contrast verified on 7 key foreground/background pairs - All semantic tokens resolve; no missing references - Dark mode parity confirmed across 8 components and 7 pages - Visual smoke via Playwright confirms Cinzel loads and terracotta renders Final Wave: F1 APPROVE | F2 APPROVE | F3 APPROVE | F4 APPROVE * fix(canonical): align canonical URL with metadataBase Canonical URLs in blog and project detail pages used the old tomsegbers.de domain, mismatching metadataBase (https://tom.segbers.de). Updated to match. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * refactor: wire Button component into homepage and remove dead ProjectTeaser.imageUrl Replaced two inline hero CTAs with existing Button component (primary/secondary lg variants). Removed unused imageUrl prop from ProjectTeaser's interface, destructure, JSDoc, test fixture, and Storybook story, plus 5 production callers. Applied readonly to re-touched ProjectProps. Deleted duplicate JPEG of hero portrait. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * feat(peak): content depth, reading UX, motion polish, a11y/performance baseline - Add rehype-pretty-code + remark-gfm for syntax-highlighted code blocks and GFM - Add reading time pill and TOC sidebar (IntersectionObserver scroll-spy) to blog detail - Add reading time pill to project detail - Add tags Zod schema + tag pills on blog/project detail pages - Add PageTransition (motion fade-in), HeroStagger (staggered hero), CardMotionWrapper (hover/tap) - All motion components respect prefers-reduced-motion via useReducedMotion() - Add /now, /uses pages with content/pages/ data layer - Add RSS feed (app/feed.xml/route.ts) - Add og-image routes (site-wide + per-blog-post) - Add BlogPosting/CreativeWork JSON-LD structured data on detail pages - Add per-post opengraph-image and canonical URL alignment - Add loading.tsx, error.tsx, global-error.tsx (App Router hygiene) - Add motion component smoke tests (CardMotionWrapper, HeroStagger, PageTransition) - Add Lighthouse CI workflow (.github/workflows/lighthouse.yml) - Add axe-playwright check to e2e static-routes spec - Rewrite DESIGN.md for Roman palette + Cinzel + Motion - Author peak-website blog post content - Wire Button component to homepage, remove dead imageUrl prop - Fix canonical URL to tom.segbers.de - Remove boilerplate TODO comment from homepage * chore: mark Final Wave F1-F4 complete — all APPROVE * chore: remove dead deps (@vercel/otel, @opentelemetry/*, prop-types, tsc, patch-package) Remove unused dependencies with zero imports across the codebase: Dependencies removed: - @vercel/otel — 3 production vulns, zero imports - prop-types — zero imports DevDependencies removed: - @opentelemetry/api, @opentelemetry/resources, @opentelemetry/sdk-node, @opentelemetry/sdk-trace-node, @opentelemetry/semantic-conventions — 5 packages, zero imports - @storybook/testing-library — deprecated package - @types/prop-types — companion to prop-types - patch-package — no patches/ directory exists, dead overhead - postinstall-postinstall — companion to patch-package - tsc@2.0.4 — wrong package shadows typescript compiler (typescript@5.3.2 kept) Scripts removed: - postinstall: npx patch-package -y (patch-package is dead) 88 transitive packages pruned. pnpm-lock.yaml regenerated. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * chore: drop Storybook (39 of 67 vulns, zero prod value) Storybook 7 (EOL) contributed 39 of 67 Dependabot advisories: tar 11 critical, axios 23 high, esbuild 1 moderate, sharp 1 high, uuid 1 moderate, elliptic 1 low. Zero production value — 3 story files existed but no stories/ directory was ever consumed. Removed: - devDependencies: storybook, @storybook/addon-essentials, @storybook/addon-interactions, @storybook/addon-links, @storybook/blocks, @storybook/nextjs, @storybook/react, @storybook/test-runner, eslint-plugin-storybook (9 packages) - scripts: storybook, test-storybook, build-storybook - .storybook/ directory (main.ts, preview.ts) - 3 .stories.tsx files (Button, ArticleTeaser, ProjectTeaser) Config changes: - .eslintrc.js: removed plugin:storybook/recommended from extends - check.yml: replaced Storybook smoke tests with Playwright e2e - coupling-graph script: removed .storybook/ from --exclude pattern 583 transitive packages pruned. pnpm-lock.yaml regenerated. Verification: build (47 pages), test (91 tests), lint (warnings only), prettier (4 pre-existing issues on unmodified files). Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * style: format pre-existing TSX files Restore repository-wide Prettier compliance without behavioral changes. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: remove stale Storybook references * chore: add pnpm audit overrides Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: record pnpm override evidence Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * build: upgrade Next and React Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: await Next 15 request APIs Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: prevent reduced-motion hydration mismatch Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: record Next 15 migration Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: restore CTA contrast Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test(e2e): align Roman token assertions Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test(e2e): serialize Chromium runner Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: record E2E contrast repair Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test(e2e): restore deterministic blog coverage * chore: migrate ESLint 8 to 9 flat config Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: document ESLint 9 migration Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * chore: tighten ESLint flat config Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: clean lint warnings in app pages Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: clean route metadata lint warnings Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test: order listing page imports Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: resolve remaining app lint warnings Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * style: use Tailwind size utilities Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * style: order motion component imports Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: use Next links in site chrome Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: update project teaser lint rules Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test(e2e): order accessibility imports Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * style: order library imports Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: record ESLint review correction Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test(e2e): capture test inventory Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test(e2e): capture full browser runs Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * feat: add Roman font and color tokens Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * feat: apply Garamond to long-form prose Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: keep tooltip text in UI font Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * feat: add homepage Roman typography checks Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test: align Roman color browser assertions Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: record Roman font verification Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: repair semantic button contrast Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: restore article teaser dark text Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test(e2e): wait for settled motion before Axe Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: record Task 7 contrast verification Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: guard homepage marquee edges Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test(e2e): harden Task 7 production audit Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: protect marquee edge text Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: record Task 7 marquee verification Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * feat: replace marquee with responsive project collection Remove animated duplicate-track marquee and opaque edge guards. Mobile uses native scroll-snap (snap-x snap-mandatory, w-screen cards); desktop uses responsive grid (md:grid-cols-2 xl:grid-cols-3). All project cards render whole within collection bounds. Dead Tailwind theme entries (spacing.112, zIndex.marquee, animation.marquee/marquee2, keyframes) removed. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test: update homepage tests for collection behavior Replace marquee assertions with collection geometry checks: scroll-snap-type at mobile, display:grid at desktop, visible card bounds within collection, keyboard Tab+Enter project link navigation. Reduced-motion test asserts native scroll-snap at mobile viewport. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: document project collection primitive Add project collection section to DESIGN.md §5: ordered semantic list, mobile snap-x snap-mandatory, desktop responsive grid. Remove marquee animation references from §6. Update motion table to reflect native scroll-snap pattern. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * test: add card geometry assertions to production audit Extend Axe audit script to verify visible project cards do not cross collection edges. Assert fullyInside for all visible cards at 375/1280 light/dark. Require TASK_7_AUDIT_URL env var (remove default port fallback). Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * docs: record Task 7 collection replacement verification Add plan, evidence ledger, boulder status, and four production screenshots (375/1280 light/dark). All gates green: Prettier, ESLint, 91/91 Jest, 47/47 build, 0 Axe contrast violations, 43/43 E2E twice, two visual QA oracles PASS. Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * feat: replace Flowbite Alert with custom InlineAlert Create components/InlineAlert/InlineAlert.tsx — semantic <div role="alert"> with success/failure variants via CVA, dismissible button using lucide-react X icon. Replace Flowbite Alert in app/contact/page.tsx. Preserve fixed positioning for success alert, mb-6 for failure alert, and dismiss behavior. lucide-react added as dependency for X dismiss icon. * feat: replace Flowbite Breadcrumb with custom Breadcrumbs Create components/Breadcrumbs/Breadcrumbs.tsx — semantic <nav aria-label> with <ol>/<li> structure per WCAG breadcrumb pattern. CSS pseudo-element separator (/, hidden on last item). Replace HiHome from react-icons/hi with lucide-react Home icon in all 4 pages. Preserve href links, truncate className, and aria-current="page" semantics on current page item. * feat: replace Flowbite Card with custom SurfaceCard Create SurfaceCard component using CVA + tailwind-merge pattern, matching the Flowbite Card two-layer structure (root article + inner content div with p-6 padding). Replaces Card imports in ProjectTeaser and ArticleTeaser with zero flowbite-react Card references remaining. * feat: replace Flowbite DarkThemeToggle with custom ThemeToggle Create ThemeToggle component using lucide-react Sun/Moon icons with CSS-driven icon visibility (no hydration mismatch). Uses same flowbite-theme-mode localStorage key as layout.tsx theme script. Updates dark-mode E2E test selector and test name to match new component. Navbar imports remain for task 12. * feat: replace Flowbite Navbar with custom SiteHeader * chore: remove flowbite-react, flowbite, react-icons, and 14 unused @radix-ui/* deps * feat: apply Roman design system — sharp edges, drop caps, gold hairlines, letter-spacing * refactor: replace Motion library with CSS-first animations * refactor: enforce Tailwind token usage — replace hardcoded sizes and colors * feat: craft pass — focus rings, empty states, microstate polish * test: Phase 4 a11y + Lighthouse + visual acceptance verification * chore: mark all 22/22 plan tasks complete Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> * fix: pnpm 9 compat — add packages field to workspace + mirror overrides in package.json * fix: lighthouse CI uses next start instead of http-server out * fix: cache playwright browsers in CI to prevent download hangs --------- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📦 Next.js Bundle Analysis for tomsegbers-deThis analysis was generated by the Next.js Bundle Analysis action. 🤖
|
| Page | Size (compressed) |
|---|---|
global |
100.35 KB (🟢 15.15 KB) |
Details
The global bundle is the javascript bundle that loads alongside every page. It is in its own category because its impact is much higher - an increase to its size means that every page on your website loads slower, and a decrease means every page loads faster.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
If you want further insight into what is behind the changes, give @next/bundle-analyzer a try!
New Pages Added
The following pages were added to the bundle from the code in this PR:
| Page | Size (compressed) | First Load |
|---|---|---|
/global-error |
530 B |
100.86 KB |
/error |
576 B |
100.91 KB |
/loading |
143 B |
100.49 KB |
/api/health/route |
143 B |
100.49 KB |
/feed.xml/route |
143 B |
100.49 KB |
/robots.txt/route |
143 B |
100.49 KB |
/sitemap.xml/route |
143 B |
100.49 KB |
/blog/entry/[slug]/opengraph-image/route |
143 B |
100.49 KB |
/opengraph-image/route |
143 B |
100.49 KB |
/now/page |
4.11 KB |
104.46 KB |
/uses/page |
4.11 KB |
104.46 KB |
Ten Pages Changed Size
The following pages changed size from the code in this PR compared to its base branch:
| Page | Size (compressed) | First Load |
|---|---|---|
/_not-found/page |
143 B (🟢 3 B) |
100.49 KB |
/not-found |
3.47 KB (🟢 3.33 KB) |
103.82 KB |
/layout |
27.2 KB (🟢 -60.44 KB) |
127.55 KB |
/contact/page |
9.82 KB (🟢 -54.31 KB) |
110.16 KB |
/about/page |
5.53 KB (🟢 325 B) |
105.88 KB |
/blog/page |
8.72 KB (🟢 -63.37 KB) |
109.07 KB |
/blog/entry/[slug]/page |
5.06 KB (🟢 -53.52 KB) |
105.4 KB |
/projects/page |
25.22 KB (🟢 -55.86 KB) |
125.57 KB |
/projects/entry/[slug]/page |
4.11 KB (🟢 -54.47 KB) |
104.45 KB |
/page |
25.36 KB (🟢 -55.73 KB) |
125.7 KB |
Details
Only the gzipped size is provided here based on an expert tip.
First Load is the size of the global bundle plus the bundle for the individual page. If a user were to show up to your website and land on a given page, the first load size represents the amount of javascript that user would need to download. If next/link is used, subsequent page loads would only need to download that page's bundle (the number in the "Size" column), since the global bundle has already been downloaded.
Any third party scripts you have added directly to your app using the <script> tag are not accounted for in this analysis
Next to the size is how much the size has increased or decreased compared with the base branch of this PR. If this percentage has increased by undefined% or more, there will be a red status indicator applied, indicating that special attention should be given to this.
|
Not good enough. |
Full redesign: Flowbite→custom components, Next 15 + React 19, ESLint 9 flat config, Roman design system (drop caps, gold hairlines, sharp edges), CSS-first motion, a11y + Lighthouse QA. 22/22 tasks complete, all CI checks green.