diff options
| author | soryu <soryu@soryu.co> | 2025-12-22 04:50:25 +0000 |
|---|---|---|
| committer | soryu <soryu@soryu.co> | 2025-12-23 14:47:18 +0000 |
| commit | 0741a8b8e9a2099c82bff6d6b9ebbce9c07cad53 (patch) | |
| tree | 88cbd5fecb9ca72a04aa07f1a6db4e1a751b1fd7 /makima/frontend/src/components/Logo.tsx | |
| parent | aee2e4e784afd6d115fb5f7b40284c4efd2da966 (diff) | |
| download | soryu-0741a8b8e9a2099c82bff6d6b9ebbce9c07cad53.tar.gz soryu-0741a8b8e9a2099c82bff6d6b9ebbce9c07cad53.zip | |
Update makima FE to add initial listening system
Diffstat (limited to 'makima/frontend/src/components/Logo.tsx')
| -rw-r--r-- | makima/frontend/src/components/Logo.tsx | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/makima/frontend/src/components/Logo.tsx b/makima/frontend/src/components/Logo.tsx new file mode 100644 index 0000000..5cbde9f --- /dev/null +++ b/makima/frontend/src/components/Logo.tsx @@ -0,0 +1,130 @@ +interface LogoProps { + size?: number; + listening?: boolean; + onClick?: () => void; + className?: string; + noHoverAnimation?: boolean; +} + +export function Logo({ + size = 160, + listening = false, + onClick, + className = "", + noHoverAnimation = false, +}: LogoProps) { + const shellSize = size * 1.4375; // 230/160 ratio + const haloSize = size * 1.3125; // 210/160 ratio + + return ( + <div + className={`relative grid place-items-center ${className}`} + style={{ + width: shellSize, + height: shellSize, + filter: "drop-shadow(0 10px 26px rgba(12, 35, 67, 0.32))", + }} + > + <div + className={`logo-shell ${listening ? "listening" : ""} ${noHoverAnimation ? "no-hover-animation" : ""} ${onClick ? "cursor-pointer" : ""}`} + style={{ width: shellSize, height: shellSize }} + onClick={onClick} + role={onClick ? "button" : undefined} + tabIndex={onClick ? 0 : undefined} + onKeyDown={ + onClick + ? (e) => { + if (e.key === "Enter" || e.key === " ") { + e.preventDefault(); + onClick(); + } + } + : undefined + } + > + <span className="scan-sweep" /> + <span className="scan-sweep sweep-2" /> + <svg + className="logo-svg" + viewBox="0 0 120 120" + xmlns="http://www.w3.org/2000/svg" + style={{ width: size, height: size }} + role="img" + aria-label="Makima logo" + > + <circle + className="ring ring-outer" + cx="60" + cy="60" + r="52" + strokeWidth="4" + /> + <circle + className="ring ring-middle" + cx="60" + cy="60" + r="36" + strokeWidth="3" + /> + <circle + className="ring ring-inner" + cx="60" + cy="60" + r="22" + strokeWidth="3" + /> + <circle className="core" cx="60" cy="60" r="8" /> + </svg> + </div> + <div + className="halo" + aria-hidden="true" + style={{ width: haloSize, height: haloSize }} + /> + </div> + ); +} + +// Small logo for header +export function LogoMark({ size = 32 }: { size?: number }) { + return ( + <span + className="inline-flex items-center justify-center" + style={{ width: size, height: size }} + aria-hidden="true" + > + <svg + width={size} + height={size} + viewBox="0 0 24 24" + xmlns="http://www.w3.org/2000/svg" + > + <circle + cx="12" + cy="12" + r="10" + fill="none" + stroke="#0f3c78" + strokeWidth="2" + /> + <circle + cx="12" + cy="12" + r="7" + fill="none" + stroke="#0f3c78" + strokeWidth="1.6" + /> + <circle + cx="12" + cy="12" + r="4" + fill="none" + stroke="#0f3c78" + strokeWidth="1.6" + /> + <circle cx="12" cy="12" r="1.6" fill="#0f3c78" /> + </svg> + </span> + ); +} |
