/* ============================================================ FLORÍADE — Ornamentos (React) Roda alquímica, selos, divisores, raios solares, glifos ============================================================ */ /* hooks do React disponíveis globalmente para os demais arquivos babel */ Object.assign(window, { useState:React.useState, useEffect:React.useEffect, useCallback:React.useCallback, useRef:React.useRef, useContext:React.useContext, useMemo:React.useMemo, createContext:React.createContext, useReducer:React.useReducer }); const ZODIAC = ["♈","♉","♊","♋","♌","♍","♎","♏","♐","♑","♒","♓"].map(g=>g+"\uFE0E"); const PLANETS = ["☉","☽","☿","♀","♂","♃","♄"].map(g=>g+"\uFE0E"); const ELEMENTS = ["🜂","🜁","🜄","🜃"]; // fogo, ar, água, terra function polar(cx, cy, r, deg){ const a = (deg - 90) * Math.PI/180; return [cx + r*Math.cos(a), cy + r*Math.sin(a)]; } /* Anel de glifos distribuídos (colorFn opcional para colorir por glifo) */ function GlyphRing({ glyphs, r, size, cx=200, cy=200, color="var(--gold)", colorFn, opacity=1 }){ return glyphs.map((g,i)=>{ const [x,y] = polar(cx,cy,r, i*360/glyphs.length); const c = colorFn ? colorFn(g,i) : color; return ( {g} ); }); } /* Sol = ouro, Luna = prata, demais = ouro */ const solLunaColor = (g)=> g.indexOf("☽")>=0 ? "var(--silver)" : "var(--gold)"; /* Raios concêntricos (sol radiante, estilo gravura) */ function rays(cx, cy, rIn, rOut, count, w){ const arr=[]; for(let i=0;i); } return arr; } /* ---------- EMBLEMA SOL·LUNA (coniunctio) ---------- */ /* Disco solar de ouro e crescente de prata lado a lado — as núpcias químicas. */ function SolLuna({ size=72, breathe=false, className="", style={} }){ const uid = (React.useId ? React.useId() : "sl").replace(/[:]/g,""); const mid = "slmoon-"+uid; const sx=-12, sy=0; // centro do Sol return ( ); } /* ---------- RODA ALQUÍMICA (centro do herói) ---------- */ function AlchemicalWheel({ size=520, spin=true, rays:showRays=true }){ const sc = spin ? "" : " "; return ( ); } /* ---------- LOGO (sprite inline, tintável por color) ---------- */ function Logo({ size, gold=false, className="", style={} }){ const s = size ? { width:size, height:size } : {}; return ( ); } /* ---------- SELO DA MARCA (logo em anel duplo: prata + ouro) ---------- */ function Seal({ size=120, ring=true, glyphs=true, className="" }){ return (
{ring && ( )}
); } /* ---------- DIVISOR ORNAMENTAL ---------- */ function Divider({ glyph="✥", wide=false }){ return (
{glyph}
); } /* ---------- Glifo decorativo inline ---------- */ function Glyph({ g, className="" }){ return ; } /* ---------- Microinteração: glifo voa até o carrinho ---------- */ function flyToCart(srcEl, glyph="☉"){ try{ const cart = document.querySelector(".cart-btn"); if(!cart || !srcEl) return; if(window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches) return; const a = srcEl.getBoundingClientRect(), b = cart.getBoundingClientRect(); const x0 = a.left+a.width/2, y0 = a.top+a.height/2; const dx = (b.left+b.width/2) - x0, dy = (b.top+b.height/2) - y0; const fly = document.createElement("span"); fly.textContent = glyph; fly.className = "fly-glyph"; fly.style.left = x0+"px"; fly.style.top = y0+"px"; fly.style.color = glyph.indexOf("☽")>=0 ? "var(--silver)" : "var(--gold)"; document.body.appendChild(fly); const anim = fly.animate([ { transform:"translate(-50%,-50%) translate(0,0) scale(1) rotate(0deg)", opacity:1 }, { transform:`translate(-50%,-50%) translate(${dx*0.5}px, ${dy*0.5 - 70}px) scale(1.1) rotate(120deg)`, opacity:1, offset:0.5 }, { transform:`translate(-50%,-50%) translate(${dx}px, ${dy}px) scale(.25) rotate(300deg)`, opacity:0.1 } ], { duration:780, easing:"cubic-bezier(.45,.05,.5,1)" }); anim.onfinish = ()=> fly.remove(); }catch(e){} } /* Injeta o sprite da logo inline (referências a arquivo externo falham em alguns runtimes) */ function injectSprite(){ if(document.getElementById('fl-sprite-holder')) return; fetch('assets/floriade-sprite.svg').then(r=>r.text()).then(t=>{ const div=document.createElement('div'); div.id='fl-sprite-holder'; div.setAttribute('aria-hidden','true'); div.style.cssText='position:absolute;width:0;height:0;overflow:hidden'; div.innerHTML=t; document.body.insertBefore(div, document.body.firstChild); }); } injectSprite(); Object.assign(window, { AlchemicalWheel, Seal, Divider, Glyph, GlyphRing, Logo, SolLuna, flyToCart, ZODIAC, PLANETS, ELEMENTS, polar });