Skip to content

Redesign the site with the Signal design - #53

Merged
dinooo13 merged 16 commits into
mainfrom
design/redesign-explorations
Sep 29, 2026
Merged

dinooo13 merged 16 commits into
mainfrom
design/redesign-explorations

Conversation

@dinooo13

@dinooo13 dinooo13 commented Sep 29, 2026 •

Copy link
Copy Markdown
Owner

Redesigns fmeyer.dev with the Signal design, picked from three switchable explorations (Editorial, Signal, Studio) that were built and compared on this PR's preview. The other two and the switcher have been removed; Signal is now the only design and is prerendered like the old site.

What changes for visitors

  • Look: dark-first (light mode fully supported), with a fading engineering grid and a blue glow behind the hero. The type is Geist and Geist Mono, with a floating glass nav and glowing cards.
  • Hero: leads with Fabian, not the employer. Name, role, and "I help companies make the move to agentic engineering." An agent-session terminal shows the spec → code → verify workflow and links to the Rheinwerk workshop.
  • Homepage order: Focus → Experience (the three most recent roles, "Show earlier roles" for the rest) → Speaking → Labs.
  • Every page ends with a "Let's talk." contact card (email plus profiles).
  • Labs: two-column cards, and the whole card is clickable. Detail pages have a manifest panel and a challenge → approach → next steps flow with a roadmap terminal.
  • Speaking: talk rows with a date block and an "Upcoming" chip. Detail pages have a session spec sheet, the abstract, and resource cards.
  • Error pages use the same layout.

Under the hood

  • AppHeader / AppFooter / layouts/default.vue form the site shell. Pages keep data loading, SEO and schema-org and render HomeView, LabsView, SpeakingView, LabDetailView, TalkDetailView.
  • app/assets/css/signal.css holds the theme: tokens for light and dark, Nuxt UI overrides, and the signal-* component classes.
  • useNow() keeps the time-dependent "Upcoming" badges hydration-safe on the static build.
  • Removed the classic landing components and cards, the unused template stock photos in public/hero (about 3.2 MB), and the exploration tooling.
  • CLAUDE.md describes the new structure and conventions (stretched-link cards, useNow(), reduced-motion coverage in signal.css).

Fixes to bugs on the live site

  • Nested <h1>: the homepage and every detail page rendered an <h1> inside UPageHero's own <h1>. Every page now has exactly one.
  • Duplicate theme-color: after hydration there were four theme-color meta tags instead of two, because unhead couldn't match its keyed entries to the prerendered pair.
  • Contrast: the yellow "WIP" and talk-list badges failed WCAG AA contrast.
  • 3.2 MB of PDF prefetches: every page prefetched the three bundled talk-slide PDFs. On throttled mobile they compete with the page's own resources; Lighthouse's simulated LCP reached about 19 s on the home and speaking pages. PDFs are now excluded from prefetch/preload but stay bundled and linked.

Verification

  • pnpm lint, pnpm typecheck and pnpm generate pass (0 prerender errors, 35 routes)
  • Static build, 11 pages × light/dark × 1440/390 px: one <h1> each, no horizontal overflow, no broken images, no 404s, no hydration warnings or console errors
  • axe-core 4.13 (WCAG 2.0/2.1 A + AA): 0 violations in light and dark
  • Every lab card and talk row is clickable across its whole area; keyboard focus rings are visible
  • Lighthouse on the preview (10 runs: 5 pages × mobile/desktop, before the PDF fix): accessibility 96–100, best practices 100. Performance on desktop was 82–100; on mobile it was 57–95, held back by the PDF prefetches, which are now fixed. SEO showed 66–69, but the only failing audit is "blocked from indexing", which is expected on noindex previews. The 96s came from small breadcrumb touch targets, also now fixed.
  • Lighthouse re-test after the fixes, mobile: home 92 / 100 / 100 (LCP 2.7 s), speaking 95 / 100 / 100 (LCP 2.5 s), talk detail 94 / 100 / 100 (LCP 2.6 s), as performance / accessibility / best practices. CLS 0 and TBT at most 80 ms on all three.
  • Homepage JS is 589 KB uncompressed (it was 813 KB while the design switcher shipped all three designs)

🤖 Generated with Claude Code

dinooo13 and others added 2 commits September 29, 2026 15:59
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Three switchable redesign directions for the homepage, labs, and speaking
pages, each with its own shell and scoped styles. Detail pages reuse their
existing markup inside each design's shell.

Also reveal the app only after the remounted page resolves, make the
in-page switch wait for the new page before the view transition, and
prerender the design-only portrait sizes so static previews don't 404.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dinooo13 and others added 2 commits September 29, 2026 17:32
UPageHero renders its title slot inside an <h1>, so the homepage and the
lab/talk detail pages ended up with an <h1> nested in another <h1>. Use
phrasing content in those slots instead.

Detail pages now render a design-specific LabDetail/TalkDetail component
when a non-classic design is active, and theme-color follows the design.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Each exploration now renders its own LabDetail and TalkDetail instead of
restyling the classic detail markup through CSS, so the selector hacks
are gone. Also:

- Editorial: portrait in the first mobile screen, calmer Trajectory copy,
  masthead fits down to 320px
- Signal: terminal wraps instead of truncating on mobile, tidier
  portrait/status row, a more deliberate light-mode terminal
- Studio: featured-lab tile degrades gracefully for other labs, bento
  clears the design switcher at 1440x900
- Prerender the portrait sizes the new layouts request

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The two keyed theme-color entries got different dedupe ids on the client
than the prerendered tags, so unhead inserted a second pair (also on the
live site). Drop the keys so unhead matches the pair by position, and
drive the values reactively from the active design instead of mutating
the DOM.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Lab status and talk-list badges used Nuxt UI's soft warning/info
  colours, which fail AA contrast (13 nodes on /labs, also live on the
  site). Use neutral; the label and icon carry the status.
- Studio talk facts wrapped dt/dd in an extra div next to the icon,
  which breaks the description list. Keep each group as div > dt + dd
  and position the decorative icon inside the dt.

axe-core 4.13 (wcag2a/aa, wcag21a/aa) now reports 0 violations across
all four designs, five routes, light and dark.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Add optional metrics and highlights to the labs schema and fill them in
for Pladder and Habit Tracker. Signal's stat strip and terminal, and
Studio's featured tile and lab cards, read these fields instead of
pattern-matching the description text, so copy edits can no longer
silently change or drop the numbers.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Production builds resolve bundled PDFs to absolute /_nuxt/ URLs, so the
relative-URL check treated them as external and printed the hashed asset
path.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
dinooo13 and others added 2 commits September 29, 2026 22:33
Signal becomes the site's only design and is now prerendered:
- AppHeader/AppFooter and the default layout are the Signal shell
  (glass nav, grid + glow backdrop, "Let's talk" contact card)
- Pages keep data loading, SEO and schema-org and render *View
  components (HomeView, LabsView, SpeakingView, LabDetailView,
  TalkDetailView); LabCard, TalkRow, SectionHeader, AgentSession move
  to app/components
- signal.css is unscoped into the global theme; fonts are Geist and
  Geist Mono
- useNow() keeps time-dependent "Upcoming" badges hydration-safe
- Homepage: focus, experience (three most recent roles, expandable),
  speaking, labs; no stat strip or benchmark lines; whole lab cards
  clickable
- Hero copy: "I help companies make the move to agentic engineering"

Removed: the design switcher and boot script, Editorial, Studio, the
classic landing components and cards, the portrait prerender list, and
the lab metrics/highlights fields that only the explorations used.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
public/hero/random-*.avif were left over from the Nuxt portfolio
template and not referenced anywhere (about 3.2 MB deployed).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dinooo13 dinooo13 changed the title Design explorations: Editorial, Signal, and Studio (switchable) Redesign the site with the Signal design Sep 29, 2026
Drop violet from the palette: gradients now run saturated blue -> sky ->
teal (the old cyan end becomes a greener teal, token renamed to
--signal-teal). The name gradient starts earlier so more of it shows,
and the glow, monogram, terminal bezel, borders and terminal step
colours follow the same palette. All stops keep AA contrast in light
and dark.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Lighthouse on the preview showed every page prefetching the three
bundled talk-slide PDFs (~3.2 MB; also on the live site). On throttled
mobile they compete with the page's own resources, pushing simulated
LCP to ~19 s on the home and speaking pages. Exclude PDFs from the
build manifest's prefetch/preload; they stay bundled and linked.

Breadcrumb links now have a 24x24px minimum target (WCAG 2.5.8), which
Lighthouse flagged on the detail pages.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The Motion wrappers were only used for fade-in-on-scroll, but motion-v
put ~40 KB gzip of JS on every page's critical path (~85 KB total).
List items now use the signal-reveal class: a CSS scroll-driven
animation (animation-timeline: view()) that needs no JavaScript, keeps
items already in view at their end state, and simply shows content in
browsers without view timelines. Reduced motion disables it.

Removes the motion-v module and dependency and updates CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@dinooo13
dinooo13 merged commit c0b16e5 into main Sep 29, 2026
8 checks passed
@dinooo13
dinooo13 deleted the design/redesign-explorations branch September 30, 2026 19:48
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