From 6150b56a5c6816ad05d578567daab47b9db35659 Mon Sep 17 00:00:00 2001 From: wassgha Date: Wed, 8 Jul 2026 21:18:54 -0700 Subject: [PATCH] siri theme --- .../src/components/themes/siri/index.tsx | 391 ++++++++++++++++++ src/renderer/src/styles/globals.css | 36 ++ 2 files changed, 427 insertions(+) create mode 100644 src/renderer/src/components/themes/siri/index.tsx diff --git a/src/renderer/src/components/themes/siri/index.tsx b/src/renderer/src/components/themes/siri/index.tsx new file mode 100644 index 0000000..9d230cd --- /dev/null +++ b/src/renderer/src/components/themes/siri/index.tsx @@ -0,0 +1,391 @@ +import { useRef } from "react"; +import type { CSSProperties } from "react"; +import { MinimalShell } from "../shared/minimal-shell"; +import { OverlayTranscript } from "../shared/overlay-transcript"; +import { useAmplitudeFrame, ACTIVE_STATES } from "../shared/use-amplitude"; +import type { DexStatus } from "@/lib/dex/state"; +import type { DexThemeProps, DexThemeDef } from "../types"; + +// A Siri-style glass orb. The aurora is NOT blurred blobs — it's SVG ribbon +// paths (a blue wave over a white-hot crease over an orange/red wave) with +// linear gradients and per-ribbon gaussian blur, clipped to the sphere, so the +// swoosh has crisp directional edges like the real thing. Colors stay anchored +// (blue left/top, red right/bottom — no hue cycling); motion is a slow per- +// ribbon undulation. Voice loudness (`--amp`, one CSS var written per frame) +// swells the band, brightens it, and scales the orb via calc() — zero React +// re-renders. + +const RAINBOW = + "conic-gradient(from 210deg, #34d8ff, #3b6bff, #b56bff, #ff375f, #ffb340, #7dffb0, #34d8ff)"; + +// Slow organic undulation for one ribbon; duration/delay/direction vary per +// path so the band never visibly repeats. +function ripple(dur: number, delay: number, reverse = false): CSSProperties { + return { + transformBox: "fill-box", + transformOrigin: "50% 50%", + animation: `dex-siri-wave ${dur}s ease-in-out ${delay}s infinite ${ + reverse ? "reverse" : "normal" + }`, + }; +} + +function SiriOrb({ + status, + getAmplitude, +}: Pick) { + const orbRef = useRef(null); + + useAmplitudeFrame(getAmplitude, ACTIVE_STATES.has(status), (a) => { + orbRef.current?.style.setProperty("--amp", a.toFixed(3)); + }); + + // Idle stays vivid (the real orb rests in full color) — only muted/broken dim. + const dim = ["muted", "unsupported", "error"].includes(status); + + return ( +