/* global React */
// Header + footer + shared chrome
/* DeltaStrat — symbol
Equilateral, open delta.
- Two white edges run from base corners up to a sharp apex (closed apex).
- The bottom side is BROKEN: a small cut/gap divides white left segment
from a short cyan segment on the right.
- The bottom-right of the triangle has a small DIAGONAL CUT — the right
edge does not meet the base; it terminates above the baseline and the
cyan segment sits on the cut.
- Sharp corners, consistent stroke, no glow, no gradient. */
function DeltaMark({ size = 22, strokeWidth }) {
/* Geometry — reference-exact
* ViewBox 0 0 34 30 (≈1.13:1, slightly wider than tall)
*
* Apex : (17, 2)
* BL : ( 2, 29)
* BR : (32, 29)
*
* Segments
* --------
* White left edge : apex → BL (full diagonal)
* White right edge : apex → BR (full diagonal — reaches baseline)
* White left base : BL → (13, 29) short horizontal
* GAP : 13 → 19 (6 units, clearly visible)
* Cyan right base : (19, 29) → BR horizontal, same baseline
*/
const sw = strokeWidth ?? Math.max(1.4, size / 14);
const h = Math.round(size * 0.88);
return (
);
}
/* Wordmark — custom engineered letterforms
Modifications applied via SVG mask (runtime measurement):
· E: middle bar removed → open, segmented look
· A: crossbar removed → sharp apex, open feel
Tracking: +12%. DELTA white, STRAT cyan. Extra word gap.
*/
function Wordmark({ scale = 1, withSubtitle = false, subtitle, align = 'left' }) {
const svgRef = React.useRef(null);
const [cuts, setCuts] = React.useState([]);
const [svgW, setSvgW] = React.useState(null);
const fontSize = Math.round(18 * scale);
const wordGap = Math.round(fontSize * 0.55);
const subSize = Math.round(fontSize * 0.66);
React.useEffect(() => {
const svg = svgRef.current;
if (!svg) return;
const measure = () => {
const textEl = svg.querySelector('#wm-main');
if (!textEl || typeof textEl.getExtentOfChar !== 'function') return;
try {
const c = [];
// E (charnum 1 in "DELTASTRAT"): erase middle bar
const e = textEl.getExtentOfChar(1);
c.push({ x: e.x + e.width*0.14, y: e.y + e.height*0.34, w: e.width*0.86, h: e.height*0.30 });
// A in DELTA (charnum 4): erase crossbar
const a1 = textEl.getExtentOfChar(4);
c.push({ x: a1.x + a1.width*0.14, y: a1.y + a1.height*0.43, w: a1.width*0.72, h: a1.height*0.19 });
// A in STRAT (charnum 8): erase crossbar
const a2 = textEl.getExtentOfChar(8);
c.push({ x: a2.x + a2.width*0.14, y: a2.y + a2.height*0.43, w: a2.width*0.72, h: a2.height*0.19 });
setCuts(c);
// Set explicit SVG width so text doesn't overflow into nav
const totalW = textEl.getComputedTextLength();
const measured = Math.ceil(totalW) + 4;
setSvgW(measured);
// Also set directly on the DOM element to avoid React re-render delay
if (svg) svg.setAttribute('width', String(measured));
} catch (_) { /* font metrics unavailable — fallback to unmodified */ }
};
if (document.fonts) {
document.fonts.ready.then(() => requestAnimationFrame(measure));
} else {
setTimeout(measure, 500);
}
}, [fontSize]);
const svgH = fontSize + 4;
const mId = 'wm-mask';
return (
{withSubtitle && subtitle && (
{subtitle}
)}
);
}
function Logo({ onClick, size = 'sm', withSubtitle = false, subtitle }) {
const cfg = {
sm: { mark: 24, scale: 0.82, gap: 0, divH: 36 }, // header
md: { mark: 32, scale: 1.15, gap: 0, divH: 48 }, // footer
lg: { mark: 64, scale: 2.40, gap: 0, divH: 0 }, // hero
}[size] || { mark: 24, scale: 0.82, gap: 0, divH: 36 };
return (
);
}
function Header({ lang, setLang, route, navigate, t }) {
const [scrolled, setScrolled] = useState(false);
const [mobileOpen, setMobileOpen] = useState(false);
useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 8);
onScroll();
window.addEventListener('scroll', onScroll, { passive: true });
return () => window.removeEventListener('scroll', onScroll);
}, []);
useEffect(() => { setMobileOpen(false); }, [route.page, route.slug]);
useEffect(() => {
document.body.style.overflow = mobileOpen ? 'hidden' : '';
return () => { document.body.style.overflow = ''; };
}, [mobileOpen]);
const navItems = [
{ key: 'home', label: t.nav.home },
{ key: 'services', label: t.nav.services },
{ key: 'about', label: t.nav.about },
{ key: 'certifications', label: t.nav.certifications },
{ key: 'contact', label: t.nav.contact },
];
const isActive = (k) => route.page === k;
return (
<>
navigate('home')} withSubtitle subtitle="OFFENSIVE SECURITY · APPLICATION SECURITY"/>
{/* Desktop nav */}
{/* Mobile panel */}
{navItems.map((item, i) => (
))}
>
);
}
function LangSwitch({ lang, setLang }) {
return (
{LANGS.map((code) => {
const isActive = lang === code;
const label = code === 'pt-BR' ? 'PT' : 'EN';
return (
);
})}
);
}
function Footer({ t, navigate, lang, setLang }) {
const s = t.home;
const now = new Date();
const time = now.toLocaleTimeString(lang === 'pt-BR' ? 'pt-BR' : 'en-US',
{ hour: '2-digit', minute: '2-digit', hour12: false, timeZone: 'America/Sao_Paulo' });
return (
);
}
function FooterCol({ title, items, onClick }) {
return (
{title}
{items.map((it, i) => (
-
))}
);
}
Object.assign(window, { Header, Footer, Logo, LangSwitch });