// Hi-fi V3: annotated full-bleed — responsive (mobile + desktop)
const { EmailSVG: HiFiEmail } = window;
function useWindowWidth() {
const [w, setW] = React.useState(window.innerWidth);
React.useEffect(() => {
const fn = () => setW(window.innerWidth);
window.addEventListener('resize', fn);
return () => window.removeEventListener('resize', fn);
}, []);
return w;
}
// ─── Icons ────────────────────────────────────────────────────────────────────
function RefinedGear({ stroke, sw = 1.5 }) {
const teeth = [];
for (let i = 0; i < 10; i++) {
const a = (i * Math.PI * 2) / 10 - Math.PI / 2;
const x1 = 50 + Math.cos(a) * 30;
const y1 = 50 + Math.sin(a) * 30;
const x2 = 50 + Math.cos(a) * 40;
const y2 = 50 + Math.sin(a) * 40;
teeth.push();
}
return (
{teeth}
);
}
function RefinedCamera({ stroke, sw = 1.5 }) {
return (
);
}
function RefinedCode({ stroke, sw = 1.8 }) {
return (
);
}
const REFINED_ICONS = ['gear', 'camera', 'code'];
const REFINED_LABELS = { gear: 'engineering', camera: 'photography', code: 'coding' };
function RefinedShape({ name, stroke, sw }) {
if (name === 'gear') return ;
if (name === 'camera') return ;
if (name === 'code') return ;
return null;
}
// ─── Morph animation ──────────────────────────────────────────────────────────
function RefinedMorph({ size = 360, style = 'crossfade', speed = 1, accent = 'currentColor' }) {
const [active, setActive] = React.useState(0);
const [phase, setPhase] = React.useState('in');
React.useEffect(() => {
const HOLD = 1800 / speed;
const TRANS = 700 / speed;
let timer;
const cycle = () => {
setPhase('in');
timer = setTimeout(() => {
setPhase('hold');
timer = setTimeout(() => {
setPhase('out');
timer = setTimeout(() => {
setActive((a) => (a + 1) % REFINED_ICONS.length);
}, TRANS);
}, HOLD);
}, TRANS);
};
cycle();
return () => clearTimeout(timer);
}, [active, speed]);
const name = REFINED_ICONS[active];
let transform = 'none';
let opacity = 1;
if (style === 'crossfade') {
if (phase === 'in') { transform = 'scale(0.92) rotate(-4deg)'; opacity = 0; }
if (phase === 'hold') { transform = 'scale(1) rotate(0deg)'; opacity = 1; }
if (phase === 'out') { transform = 'scale(1.08) rotate(4deg)'; opacity = 0; }
} else if (style === 'redraw') {
transform = 'none';
opacity = phase === 'out' ? 0 : 1;
} else if (style === 'spin') {
if (phase === 'in') { transform = 'rotate(-180deg) scale(0.5)'; opacity = 0; }
if (phase === 'hold') { transform = 'rotate(0deg) scale(1)'; opacity = 1; }
if (phase === 'out') { transform = 'rotate(180deg) scale(0.5)'; opacity = 0; }
} else if (style === 'slide') {
if (phase === 'in') { transform = 'translateY(24px)'; opacity = 0; }
if (phase === 'hold') { transform = 'translateY(0)'; opacity = 1; }
if (phase === 'out') { transform = 'translateY(-24px)'; opacity = 0; }
}
const transitionMs = (style === 'redraw' ? 900 : 600) / speed;
return (
— {REFINED_LABELS[name]} —
);
}
// ─── Shared pieces ────────────────────────────────────────────────────────────
function PortraitPlaceholder({ accent }) {
return (
);
}
function LinkedInLinkHF({ accent }) {
return (
LinkedIn ↗
);
}
function GridBGHF() {
return (
);
}
function RegisterMark({ style }) {
return (
);
}
const mono = 'JetBrains Mono, ui-monospace, monospace';
const serif = 'Instrument Serif, Georgia, serif';
const label = { fontFamily: mono, fontSize: 9, letterSpacing: '0.25em', textTransform: 'uppercase', color: 'var(--ink-soft)' };
// ─── Mobile layout ────────────────────────────────────────────────────────────
function MobileLayout({ animationStyle, accent, speed }) {
return (
{/* Identity row */}
hello, I'm
Switzerland · CH
{/* Name */}
Christoph
Philipp
{/* Morph icon */}
{/* Roles */}
✶ what I am
problem solver,
technology geek,
creative,
family father.
{/* About */}
↘ about
Knowledge that extends into mechanics, electronics, software, IT, and agile development tools.
{/* Off-hours */}
off-hours
Sports, photography, knowledge, coding — the loop keeps spinning.
{/* Contact */}
{/* Year */}
© 2026
);
}
// ─── Desktop layout (scaled to fit viewport) ──────────────────────────────────
function DesktopLayout({ animationStyle, accent, speed, viewportWidth }) {
const scale = Math.min(1, viewportWidth / 1200);
const scaledHeight = Math.round(800 * scale);
return (
{/* center: huge morph */}
{/* TOP-LEFT: identity */}
hello, I'm
Switzerland · CH
Christoph
Philipp
{/* TOP-RIGHT: roles */}
✶ what I am
problem solver,
technology geek,
creative,
family father.
{/* MID-LEFT: about */}
↘ about
Knowledge that extends into mechanics, electronics, software, IT, and agile development tools.
{/* MID-RIGHT: off-hours */}
off-hours ↙
Sports, photography, knowledge, coding — the loop keeps spinning.
{/* BOTTOM: contact bar */}
{/* year */}
© 2026
);
}
// ─── Main export ──────────────────────────────────────────────────────────────
function HiFiV3({ animationStyle, accent, speed }) {
const w = useWindowWidth();
if (w < 768) {
return ;
}
return ;
}
window.HiFiV3 = HiFiV3;