Almost ten years ago I had already rebuilt this website from scratch – back then with React, TypeScript, Redux and an ASP.NET Core backend (see Creating www.carecom.de). The stack felt fresh and exciting in 2017, but like everything on the web it has acquired a distinct patina since. Time for a relaunch then – with everything C# and .NET have to offer in 2026.
The new carecom.de now runs as a Blazor Web App on .NET 10, with server-side pre-rendering and interactive components only where they actually pay off (contact form, cookie banner, photo slider, mini Space Invaders). No JavaScript framework in the background, no Redux pipeline – just type-safe C# all the way into the UI components, and a compact custom CSS without Bootstrap.
That much is the usual story. What's actually interesting is not what is written there, but who wrote it: well over 99% of the code – Razor components, CSS, service classes, configuration – came from Claude Code, Anthropic's agentic CLI tool. Across a series of sessions I supplied the goals and the iterations; the agent planned, wrote, tested, corrected and proposed the next step.
How it went
We started with a short requirements pass – hosting model, localization, UI framework. Immediately afterwards Claude scraped the old website page by page, extracted the texts verbatim and saved the images locally with the original folder structure. Over several iterations that grew into a full clone that comes very close to the original in both look and content – and picked up its own improvements along the way.
Components and layout shell
The architecture focuses on reusable components: SiteHeader, SiteFooter, PageHeaderRow, LanguageSwitcher, RightSidebar, PersonCard, BlogTeaser, ReferenceList, QuoteBlock, Testimonial, PhotoSlider, TextCarousel, CookieConsent, SeoTags, SocialIcons, LatestPosts, SpaceInvaders – wherever the same pattern showed up in more than one place, it became its own Razor component.
A common SitePage shell sits across all content pages with named slots: BeforeMain for full-bleed elements above the container (Home carousel, Photography slider), ChildContent as the main column, Sidebar as an optional extension to the auto-derived child menu, and Aside as a full replacement for the default sidebar (Contact with two PersonCards). Each page inherits from PageBase, which keeps Lang/Effective centrally — so the per-page boilerplate disappears entirely.
Multi-language — declarative
Localization via URL prefix (/de/…, /en/…) with a language switcher in the top right of the SiteHeader. Genuinely bilingual texts (same DOM shape, different words) live as type-safe L(De, En) records in a central SiteContent.cs, generated by a source generator from one XML file per section. SiteContent.Contact.Phone[Effective] returns the right variant — no IStringLocalizer ceremony, no .resx generation.
For structural language branches in the markup — entire DE-only sections like the IT-consulting block on the Consulting page, or different DOM shapes per language — there are two tiny Razor components: <De> and <En>. They read the active language via [CascadingParameter(Name = "Lang")] from a MainLayout-level cascade that is itself fed directly from the URL path. The pair replaces dozens of @if (Effective == "de") blocks with declarative markup that reads like HTML.
Photography
The Photography page runs a 42-image slider that spans the full browser width — but with a fixed 3:2 aspect ratio matching the original 1920×1280 files, and object-fit: contain. On normal screens every photo lands edge-to-edge, perfectly fitted; on very large displays a max-height: 70vh cap keeps the slider in proportion, with the slim horizontal letterbox as the conscious trade-off versus vertical cropping. Captions and navigation arrows fade in only on hover, so the image takes centre stage. On touch devices without hover capability the controls stay visible permanently.
Brand animation: caredef as a choreographed SVG
The favicon wasn't hand-drawn – it was generated straight from the wordmark: Claude computed the bounding box of the first "C" in carecom.png using a pixel-density profile, sampled the dominant colour (#10AE5B – the CARECOM green) and rendered 32×32, 64×64 and 192×192 favicons from it.
The old caredef.jpg on the brand page (The CARECOM Brand) has since been turned into an animated SVG end-to-end: the CARECOM® wordmark as a base64-embedded PNG (pixel-perfect letterform — no installed font reproduces it), the seven satellite words (Competence, Commitment, Communication, Computer, Complete, Competitive, Common Sense) and the phonetic caption as real SVG text elements at their original positions. On view, the logo springs in (spring-easing with a slight overshoot), the seven words fade in sequentially at 150-ms intervals from slightly outward-offset positions, and the caption flies up from below at the end. prefers-reduced-motion is respected.
Easter egg: Space Invaders in 6502 tradition
On the Informatiker / Computer-Scientist page I asked Claude to integrate a tiny Space Invaders mini-game — as a homage to my first 6502-assembly project on an Apple ][. The result is a self-contained canvas game in pure browser JS, in the site's colour scheme (accent-blue invaders on a footer-black background, graded by point value from light to dark) and with bilingual on-canvas labels.
Three paths lead to it: a "6502" anchor link inside the programming-languages list, its own /en/play route for a shareable direct link, and a classic Konami code (↑ ↑ ↓ ↓ ← → ← → B A) that jumps to the game from any page.
CSS isolation
Component-specific CSS lives consistently per component: every Foo.razor has its Foo.razor.css, which Blazor tags with a unique [b-xxxxx] scope attribute. The originally 860-line site.css has shrunk to about 150 lines – just design tokens, base typography and genuine cross-cutting patterns. At the few places where rules need to cross component boundaries (the SiteFooter anchor colour applying to nested SocialIcons anchors, the <li> border in the RightSidebar slot, the input-width rule on the field rendered by InputText inside the ContactForm), ::deep does the job.
Privacy and analytics
Google Analytics 4 is wired up as a real opt-in: without a click on "Accept" in the cookie banner, gtag.js never loads, no cookies are set, no data is sent to Google. Only after explicit consent (Art. 6 (1) (a) GDPR) does the bootstrap kick in, and a GoogleAnalyticsTracker component fires an extra page_view on every Blazor-internal navigation — without it, SPA route changes would never reach Analytics. The privacy policy describes the mechanism in its own section with a withdrawal hint. The SeoTags component sets title, description, canonical, OpenGraph and Twitter-card tags plus hreflang alternates per page.
Render modes and pitfalls
An important technical lesson that we ran into twice: a CascadingValue from a statically rendered parent does not automatically cross the render-mode boundary into an @rendermode InteractiveServer subtree. Symptom: in the contact form, labels suddenly switched to German after the interactive handover even though the page was at /en/contact; and in the Space Invaders mini-game, the intro block stubbornly showed the DE variant because the <De>/<En> consumers inside the interactive component only saw the default. The clean fix in both cases: pass Lang as an explicit [Parameter] from the page Razor, then re-publish it inside the component via <CascadingValue Value="@Lang" Name="Lang" IsFixed="true"> for its children.
Conclusion
What in the old days would have meant weeks of manual work – content migration, component splitting, pixel fidelity to the original, GDPR copy, mail layout, photo slider, favicons, localization, an animated brand SVG, a mini-game with three discovery paths, full CSS isolation – came together in a manageable number of sessions with Claude Code. My contribution was essentially goal-setting, review and the occasional course correction; the agent did the rest: plan, write, build, smoke-test, document.
If you are thinking about a similar relaunch or about agentic coding tools in your own company: feel free to get in touch!
