feat: German as the main language, English under /en, with a language switch
The site now exists in German (at the root, with /impressum and /datenschutz) and English (/en). A request without a language follows the visitor's choice from the language switch, then the browser language, then German; the old English legal addresses move to /en for good. All visible texts are data in src/content/de.ts and en.ts, so components hold none of their own. The header carries a DE/EN switch whose bit curtain covers the page while it is swapped and reopens at the same reading position. Title, description, canonical, hreflang, Open Graph, the share image, the sitemap and the structured data are per language. The privacy notice now describes the cookie that remembers the chosen language. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,8 @@ import { Button } from "@/src/components/Button";
|
||||
import { BitAura } from "@/src/components/bits/BitAura";
|
||||
import { DecodeText } from "@/src/components/bits/DecodeText";
|
||||
import { PathScene } from "@/src/components/illustrations/PathScenes";
|
||||
import { SERVICE_PATHS, type ServicePath } from "@/src/content/paths";
|
||||
import { useContent } from "@/src/components/ContentProvider";
|
||||
import type { ServicePath } from "@/src/content/types";
|
||||
|
||||
const MONO = "font-mono text-[11px] uppercase tracking-[0.2em] text-slate-500";
|
||||
const STEP_MS = 4800;
|
||||
@@ -143,16 +144,18 @@ const PathStory: React.FC<{ path: ServicePath; active: boolean }> = ({
|
||||
* All three panels stay in the DOM so the content is readable without JavaScript.
|
||||
*/
|
||||
export const PathPicker: React.FC = () => {
|
||||
const [activeId, setActiveId] = React.useState(SERVICE_PATHS[0]?.id ?? "");
|
||||
const { services } = useContent();
|
||||
const paths = services.paths;
|
||||
const [activeId, setActiveId] = React.useState(paths[0]?.id ?? "");
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
role="tablist"
|
||||
aria-label="What do you need?"
|
||||
aria-label={services.tablistLabel}
|
||||
className="grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-4 lg:gap-4"
|
||||
>
|
||||
{SERVICE_PATHS.map((path, index) => {
|
||||
{paths.map((path, index) => {
|
||||
const selected = path.id === activeId;
|
||||
return (
|
||||
<button
|
||||
@@ -187,7 +190,7 @@ export const PathPicker: React.FC = () => {
|
||||
})}
|
||||
</div>
|
||||
|
||||
{SERVICE_PATHS.map((path) => {
|
||||
{paths.map((path) => {
|
||||
const selected = path.id === activeId;
|
||||
return (
|
||||
<div
|
||||
@@ -214,7 +217,7 @@ export const PathPicker: React.FC = () => {
|
||||
</p>
|
||||
</div>
|
||||
<div className="md:col-span-5">
|
||||
<p className={`${MONO} m-0`}>What you get</p>
|
||||
<p className={`${MONO} m-0`}>{services.youGet}</p>
|
||||
<ul className="m-0 mt-4 list-none p-0">
|
||||
{path.youGet.map((item) => (
|
||||
<li
|
||||
@@ -233,12 +236,12 @@ export const PathPicker: React.FC = () => {
|
||||
</div>
|
||||
|
||||
<div className="mt-14 md:mt-24">
|
||||
<p className={`${MONO} m-0 mb-6`}>How it runs</p>
|
||||
<p className={`${MONO} m-0 mb-6`}>{services.howItRuns}</p>
|
||||
<PathStory path={path} active={selected} />
|
||||
</div>
|
||||
|
||||
<div className="mt-12 rounded-3xl bg-slate-50 p-6 md:mt-16 md:p-10">
|
||||
<p className={`${MONO} m-0`}>What it costs</p>
|
||||
<p className={`${MONO} m-0`}>{services.whatItCosts}</p>
|
||||
<div className="mt-6 grid grid-cols-1 gap-10 md:grid-cols-12 md:gap-12">
|
||||
<div className="md:col-span-6">
|
||||
<p className="m-0 font-sans text-2xl font-bold leading-tight tracking-tight text-slate-900 md:text-4xl">
|
||||
|
||||
Reference in New Issue
Block a user