/* global React */ // Brief-provided headline + subheadline pairs (exposed as a Tweak). const HEADLINES = [ { h: 'Precisão técnica em cada detalhe', sub: 'Apoio técnico a advogados e escritórios em disputas patrimoniais, judiciais, extrajudiciais ou arbitragem.' }, { h: 'Onde há dúvida, há método', sub: 'Análises técnicas que transformam questionamentos em evidências.' }, { h: 'A resposta está nos detalhes', sub: 'Perícias e avaliações conduzidas com rigor técnico e respaldo profissional.' }, { h: 'Evidências que falam por si', sub: 'Quando a decisão exige precisão, a análise técnica faz a diferença.' }, { h: 'Veja além do que é visível', sub: 'Identificamos causas, riscos e responsabilidades com metodologia e experiência.' }, ]; window.HEADLINES = HEADLINES; // Technical terms that drift behind the inspection lens. const TERMS = [ { x: 6, y: 9, s: 16, m: false, r: -4, t: 'Trincas estruturais' }, { x: 60, y: 6, s: 13, m: true, r: 0, t: 'NBR 14653' }, { x: 32, y: 19, s: 18, m: false, r: 2, t: 'Infiltrações' }, { x: 67, y: 22, s: 14, m: false, r: -3, t: 'Inspeção predial' }, { x: 5, y: 31, s: 13, m: true, r: 0, t: 'NBR 13752' }, { x: 38, y: 38, s: 20, m: false, r: 0, t: 'Vícios construtivos' }, { x: 74, y: 40, s: 14, m: false, r: 3, t: 'Laudo técnico' }, { x: 9, y: 50, s: 16, m: false, r: -2, t: 'Patologia das construções' }, { x: 56, y: 55, s: 14, m: false, r: 0, t: 'Perícia judicial' }, { x: 28, y: 63, s: 16, m: false, r: 2, t: 'Engenharia diagnóstica' }, { x: 71, y: 66, s: 13, m: false, r: -3, t: 'Parecer técnico' }, { x: 6, y: 74, s: 14, m: false, r: 0, t: 'Avaliação imobiliária' }, { x: 42, y: 81, s: 15, m: false, r: -2, t: 'Conformidade construtiva' }, { x: 67, y: 85, s: 14, m: false, r: 2, t: 'Assistência técnica' }, { x: 16, y: 91, s: 13, m: false, r: 0, t: 'Responsabilidade técnica' }, ]; function TermField({ sharp, navy, dim }) { const blurColor = navy ? 'var(--blue-300)' : 'var(--ink-400)'; const sharpColor = navy ? 'var(--cream-50)' : 'var(--blue-700)'; const cls = sharp ? 'term-layer term-layer-sharp' : ('term-layer term-layer-blur' + (dim ? ' term-layer-dim' : '')); return ( ); } // Shared inspection-lens animation: drives clip-path + reticle position via rAF. function useInspectionLens({ hostRef, sharpRef, frameRef, circle, reticle, sweep, deps }) { React.useEffect(() => { const host = hostRef.current; if (!host) return; const reduce = window.matchMedia('(prefers-reduced-motion: reduce)').matches; const { RW, RH, R } = reticle; const halfW = circle ? R : RW / 2; const halfH = circle ? R : RH / 2; const s = { hover: false, mx: sweep.cx0, my: sweep.cy0, cx: sweep.cx0, cy: sweep.cy0 }; let raf; const start = performance.now(); function tick(now) { const w = host.clientWidth || 1; const h = host.clientHeight || 1; let tx, ty; if (s.hover) { tx = s.mx; ty = s.my; } else if (reduce) { tx = sweep.cx0; ty = sweep.cy0; } else { const e = now - start; tx = sweep.cx0 + sweep.ax * Math.sin(e * sweep.fx); ty = sweep.cy0 + sweep.ay * Math.sin(e * sweep.fy + 1.2); } const k = s.hover ? 0.20 : 0.045; s.cx += (tx - s.cx) * k; s.cy += (ty - s.cy) * k; const minx = halfW / w, maxx = 1 - halfW / w; const miny = halfH / h, maxy = 1 - halfH / h; const fx = Math.min(maxx, Math.max(minx, s.cx)); const fy = Math.min(maxy, Math.max(miny, s.cy)); const x = fx * w, y = fy * h; if (sharpRef.current) { sharpRef.current.style.clipPath = circle ? 'circle(' + R + 'px at ' + x + 'px ' + y + 'px)' : 'inset(' + (y - RH / 2) + 'px ' + (w - (x + RW / 2)) + 'px ' + (h - (y + RH / 2)) + 'px ' + (x - RW / 2) + 'px)'; } if (frameRef.current) { frameRef.current.style.left = (circle ? x - R : x - RW / 2) + 'px'; frameRef.current.style.top = (circle ? y - R : y - RH / 2) + 'px'; } raf = requestAnimationFrame(tick); } raf = requestAnimationFrame(tick); const onMove = (ev) => { const r = host.getBoundingClientRect(); s.mx = (ev.clientX - r.left) / r.width; s.my = (ev.clientY - r.top) / r.height; }; const onEnter = () => { s.hover = true; }; const onLeave = () => { s.hover = false; }; host.addEventListener('mousemove', onMove); host.addEventListener('mouseenter', onEnter); host.addEventListener('mouseleave', onLeave); return () => { cancelAnimationFrame(raf); host.removeEventListener('mousemove', onMove); host.removeEventListener('mouseenter', onEnter); host.removeEventListener('mouseleave', onLeave); }; }, deps); } function LensReticle({ innerRef, width, height, circle, markColor, initialLeft, initialTop }) { return (
); } // Prova-de-autoridade row — quiet mono labels with hairline separators. function ProvaRow({ items, tone }) { const color = tone === 'inverse' ? 'var(--blue-300)' : 'var(--ink-400)'; const sep = tone === 'inverse' ? 'var(--line-cool)' : 'var(--line-warm)'; const border = tone === 'inverse' ? 'var(--line-cool)' : 'var(--line-warm)'; return (
{items.map((p, i) => ( {i > 0 && } {p.trim()} ))}
); } function InspectionPanel({ navy, circle }) { const hostRef = React.useRef(null); const sharpRef = React.useRef(null); const frameRef = React.useRef(null); useInspectionLens({ hostRef, sharpRef, frameRef, circle, reticle: { RW: 212, RH: 152, R: 98 }, sweep: { cx0: 0.5, cy0: 0.46, ax: 0.30, ay: 0.24, fx: 0.00052, fy: 0.00039 }, deps: [circle, navy], }); const markColor = navy ? 'var(--blue-300)' : 'var(--blue-600)'; return (
ÁREA DE INSPEÇÃO · FOCO NÍTIDO
); } // ── Format A — Painel: editorial split + boxed inspection panel ────────────── function PanelHero({ t, scrollTo }) { const { Button, Eyebrow } = window.MXDEngenharia_e41562; const navy = (t.panelTheme || 'Navy') !== 'Cream'; const circle = t.lensShape === 'Círculo'; const msg = HEADLINES[t.headlineIndex] || HEADLINES[0]; const prova = (t.prova || 'Perícias judiciais • Avaliações imobiliárias • Assistência técnica').split('•'); return (
{t.eyebrow}

{msg.h}

{msg.sub}

); } // ── Format B — Imersivo: full-bleed navy inspection field ──────────────────── function ImmersiveHero({ t, scrollTo }) { const { Button, Eyebrow } = window.MXDEngenharia_e41562; const msg = HEADLINES[t.headlineIndex] || HEADLINES[0]; const prova = (t.prova || 'Perícias judiciais • Avaliações imobiliárias • Assistência técnica').split('•'); const hostRef = React.useRef(null); const sharpRef = React.useRef(null); const frameRef = React.useRef(null); useInspectionLens({ hostRef, sharpRef, frameRef, circle: true, reticle: { RW: 234, RH: 234, R: 117 }, sweep: { cx0: 0.72, cy0: 0.52, ax: 0.16, ay: 0.26, fx: 0.00048, fy: 0.00037 }, deps: [], }); return (
ÁREA DE INSPEÇÃO · FOCO NÍTIDO
{t.eyebrow}

{msg.h}

{msg.sub}

Falar pelo WhatsApp
); } // ── Format C — Editorial: type-led, registration-mark title block ──────────── function EditorialHero({ t, scrollTo }) { const { Button } = window.MXDEngenharia_e41562; const msg = HEADLINES[t.headlineIndex] || HEADLINES[0]; const heroImg = t.heroImage || ''; const meta = ['CREA-SP 123.234', 'ART em todos os laudos', 'NBR 14653']; return (
{/* left-anchored scrim — image breathes to the right */}
{!heroImg && (
foto de fundo aqui
)}
{t.eyebrow}

{msg.h}

{msg.sub}

); } function Hero({ t, scrollTo }) { const fmt = t.heroFormat || 'Imersivo'; if (fmt === 'Editorial') return ; if (fmt === 'Painel') return ; return ; } window.Hero = Hero;