/* Garbashala — shared visual components (icons, motifs, decorations) */ /* Handwrite — wraps Tegaki's custom element to draw text stroke-by-stroke in Caveat. Falls back to plain styled text if Tegaki hasn't registered yet (the upgrade fires automatically on definition). */ const Handwrite = ({ children, className = "", style = {}, color = "var(--terracotta)", size = 22, speed = 1, delay = 0, loop = false, }) => { const text = React.Children.toArray(children).filter((c) => typeof c === "string" || typeof c === "number").join(""); const fontFamily = (typeof window !== "undefined" && window.TEGAKI_FONT) || "Caveat Tegaki 3dc76002"; const props = { className: `hand-write ${className}`.trim(), text, font: fontFamily, speed: String(speed), delay: String(delay), style: { fontFamily: "var(--font-handwrite)", color, fontSize: size, lineHeight: 1.05, display: "inline-block", verticalAlign: "baseline", ...style, }, }; if (loop) props.loop = ""; return React.createElement("tegaki-renderer", props, text); }; if (typeof document !== "undefined" && !document.getElementById("handwrite-keys")) { const s = document.createElement("style"); s.id = "handwrite-keys"; s.textContent = ` @keyframes inkFade { 0% { opacity: 0; transform: translateY(2px) rotate(-1deg); } 100% { opacity: 1; transform: translateY(0) rotate(0); } } /* hide the SEO/readable text-content fallback once tegaki has rendered its shadow-DOM canvas; the engine's :host content sits in shadow root */ tegaki-renderer:defined { font-size: inherit; } `; document.head.appendChild(s); } const Diya = ({ size = 40, lit = true }) => ( {lit && ( <> )} ); const Chakra = ({ size = 200, color = "var(--terracotta)", spokes = 16 }) => { const lines = Array.from({ length: spokes }).map((_, i) => { const a = (i / spokes) * Math.PI * 2; const x1 = 50 + Math.cos(a) * 30; const y1 = 50 + Math.sin(a) * 30; const x2 = 50 + Math.cos(a) * 48; const y2 = 50 + Math.sin(a) * 48; return ; }); return ( {lines} {Array.from({ length: 8 }).map((_, i) => { const a = (i / 8) * Math.PI * 2; return ( ); })} ); }; const Foot = ({ side = "L", color = "#C4502A", size = 60, opacity = 1, rotate = 0 }) => { const flip = side === "R" ? "scale(-1, 1)" : ""; return ( {side} ); }; const Feather = ({ size = 100, rotate = 0 }) => ( {Array.from({ length: 12 }).map((_, i) => ( ))} ); const Marigold = ({ size = 60, color = "#E8A33D" }) => ( {Array.from({ length: 12 }).map((_, i) => { const a = (i / 12) * 360; return ; })} {Array.from({ length: 8 }).map((_, i) => { const a = (i / 8) * 360 + 22; return ; })} ); const HandDivider = ({ width = 600 }) => ( ); const NumberStamp = ({ n, color = "var(--terracotta)" }) => ( {n} ); const DrawPath = ({ d, stroke = "var(--terracotta)", strokeWidth = 2, fill = "none", duration = 1.6, delay = 0, ...rest }) => { const ref = React.useRef(null); React.useEffect(() => { if (!ref.current) return; const len = ref.current.getTotalLength?.() || 1000; ref.current.style.setProperty("--len", len); ref.current.style.strokeDasharray = len; ref.current.style.strokeDashoffset = len; ref.current.style.animation = `drawPath ${duration}s ${delay}s ease-out forwards`; }, [d]); return ; }; const GarbashalaLogo = ({ size = 28, accent = "var(--terracotta)", ink = "var(--ink)", showSub = true }) => ( Garba Shala garba shala {showSub && ( a garba step library )} ); const Difficulty = ({ level = 1, max = 5 }) => ( {Array.from({ length: max }).map((_, i) => ( ))} ); const NavBar = ({ active = "home" }) => (
❀ free, always
); Object.assign(window, { Handwrite, Diya, Chakra, Foot, Feather, Marigold, HandDivider, NumberStamp, DrawPath, GarbashalaLogo, Difficulty, NavBar, });