summaryrefslogtreecommitdiff
path: root/makima/frontend/src/components/Logo.tsx
diff options
context:
space:
mode:
authorsoryu <soryu@soryu.co>2025-12-22 04:50:25 +0000
committersoryu <soryu@soryu.co>2025-12-23 14:47:18 +0000
commit0741a8b8e9a2099c82bff6d6b9ebbce9c07cad53 (patch)
tree88cbd5fecb9ca72a04aa07f1a6db4e1a751b1fd7 /makima/frontend/src/components/Logo.tsx
parentaee2e4e784afd6d115fb5f7b40284c4efd2da966 (diff)
downloadsoryu-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.tsx130
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>
+ );
+}