feat: implement R42 chat infrastructure with Anthropic API integration and custom design system
This commit is contained in:
71
src/components/ui/Mark.jsx
Normal file
71
src/components/ui/Mark.jsx
Normal 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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user