feat: implement R42 chat infrastructure with Anthropic API integration and custom design system
All checks were successful
On Push to Main / test (push) Successful in 30s
On Push to Main / publish (push) Successful in 57s
On Push to Main / deploy-dev (push) Successful in 1m31s

This commit is contained in:
RaymondVerhoef
2026-05-17 16:48:40 +02:00
parent 43d01dff58
commit 98e32d8ac0
21 changed files with 2631 additions and 6 deletions

View File

@@ -0,0 +1,71 @@
import React from 'react';
/**
* Respellion brand mark — typeset directly from BallPill Light.
* Three states drive the middle glyph; braces always remain.
* idle → { r }
* typing → { … } three bouncing dots animated in CSS
* error → { ! } with a brief shake
*/
const RESP_PURPLE = '#5C1DD8';
const RESP_TEAL_900 = '#183E46';
const RESP_CREAM = '#ECE9E9';
export default function Mark({
state = 'idle',
size = 160,
theme = 'none',
brace = RESP_PURPLE,
letter = RESP_PURPLE,
showFrame = false,
ariaLabel = 'Respellion mark',
}) {
const bg =
theme === 'dark' ? RESP_TEAL_900 :
theme === 'light' ? RESP_CREAM :
'transparent';
let middle = null;
if (state === 'idle') middle = 'r';
else if (state === 'error') middle = '!';
return (
<svg
viewBox="0 0 100 100"
width={size}
height={size}
role="img"
aria-label={ariaLabel}
className={`r42-mark ${state === 'error' ? 'shake' : ''}`}
>
{showFrame && theme !== 'none' && (
<rect x="2" y="2" width="96" height="96" rx="22" fill={bg} />
)}
<text
x="50"
y="50"
fontFamily="BallPill, ui-monospace, 'JetBrains Mono', monospace"
fontSize="78"
textAnchor="middle"
dominantBaseline="central"
fontWeight="300"
style={{ letterSpacing: '-0.04em', paintOrder: 'stroke fill' }}
>
<tspan fill={brace} stroke={brace} strokeWidth="0.6">{'{'}</tspan>
{middle && <tspan fill={letter} stroke={letter} strokeWidth="0.6">{middle}</tspan>}
{state === 'typing' && <tspan fill={letter}>{' '}</tspan>}
<tspan fill={brace} stroke={brace} strokeWidth="0.6">{'}'}</tspan>
</text>
{state === 'typing' && (
<g>
<circle className="dot" cx="40" cy="50" r="3.8" fill={letter} />
<circle className="dot" cx="50" cy="50" r="3.8" fill={letter} />
<circle className="dot" cx="60" cy="50" r="3.8" fill={letter} />
</g>
)}
</svg>
);
}