feat: control room hero, SEO/AEO optimization and design system fixes

Hero: replace particle field with cobe globe (Capricorn view, multi-axis drag, reduced-motion safe), telemetry HUD with pointer parallax, particle text build effect, Space Grotesk display font. SEO: short titles with template, PT-BR accents, twitter cards on dynamic cases, escaped JSON-LD via lib/jsonld.ts, CSP report-only, 25 service FAQs answer-first. Design: fix TW4 layered reset killing spacing utilities, literal @theme tokens, mobile hero overflow, header overlap, empty case cards. Remove framer-motion (unified on motion/react), header version badge, phone number from hero CTA. Production build verified (24 static pages).
This commit is contained in:
Evandro Fonseca Junior committed 2026-08-27 10:55:21 -03:00
1 parent 0920370f30
commit b791b7de9e
94 files changed
+2621 -2889

No files matched your search

+61 -2
View File
@@ -1,6 +1,65 @@
import "@testing-library/jest-dom";
import "./__mocks__/resizeObserver";
// Mock IntersectionObserver if not available in JSDOM
if (typeof global.IntersectionObserver === "undefined") {
class IntersectionObserver {
root: Element | Document | null = null;
rootMargin: string = "";
thresholds: ReadonlyArray<number> = [];
private callback: IntersectionObserverCallback;
private elements: Set<Element> = new Set();
constructor(
callback: IntersectionObserverCallback,
options?: IntersectionObserverInit,
) {
this.callback = callback;
this.root = options?.root || null;
this.rootMargin = options?.rootMargin || "";
const threshold = options?.threshold ?? 0;
this.thresholds = Array.isArray(threshold) ? threshold : [threshold];
}
observe(target: Element) {
this.elements.add(target);
setTimeout(() => {
this.callback(
[
{
target,
isIntersecting: true,
intersectionRatio: 1,
boundingClientRect: target.getBoundingClientRect(),
intersectionRect: target.getBoundingClientRect(),
rootBounds:
this.root instanceof Element
? this.root.getBoundingClientRect()
: null,
time: Date.now(),
} as IntersectionObserverEntry,
],
this,
);
}, 0);
}
unobserve(target: Element) {
this.elements.delete(target);
}
disconnect() {
this.elements.clear();
}
takeRecords(): IntersectionObserverEntry[] {
return [];
}
}
global.IntersectionObserver =
IntersectionObserver as typeof global.IntersectionObserver;
}
// Mock PointerEvent if not available in JSDOM
if (typeof global.PointerEvent === "undefined") {
class PointerEvent extends MouseEvent {
@@ -24,8 +83,8 @@ Object.defineProperty(window, "matchMedia", {
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated
removeListener: jest.fn(), // Deprecated
addListener: jest.fn(),
removeListener: jest.fn(),
addEventListener: jest.fn(),
removeEventListener: jest.fn(),
dispatchEvent: jest.fn(),