// Chrome.jsx — shared site chrome (Header, Footer) + UI primitives
// Pages: index.html, services.html, about.html, contact.html
const FY_NAV = [
{ label: 'Home', href: 'index.html', key: 'home' },
{ label: 'Services', href: 'services.html', key: 'services' },
{ label: 'About', href: 'about.html', key: 'about' },
{ label: 'Contact', href: 'contact.html', key: 'contact' }
];
const FY_CONTACT = {
email: 'hello@fortify.gi',
address: 'Gibraltar'
};
// ---- Container -------------------------------------------------------
function Container({ children, style, className, id }) {
return (
{children}
);
}
// ---- Eyebrow ---------------------------------------------------------
function Eyebrow({ children, icon, color = 'var(--brand)', style }) {
return (
{icon && }
{children}
);
}
// ---- Button ----------------------------------------------------------
function Btn({ children, href, onClick, variant = 'primary', size = 'md', icon, iconRight, style }) {
const [hov, setHov] = React.useState(false);
const pad = size === 'lg' ? '15px 28px' : size === 'sm' ? '9px 16px' : '13px 24px';
const fs = size === 'lg' ? 16.5 : size === 'sm' ? 14 : 15.5;
const variants = {
primary: {
background: hov ? 'var(--brand-hover)' : 'var(--brand)', color: '#062229',
border: '1px solid transparent'
},
secondaryDark: {
background: hov ? 'rgba(255,255,255,.07)' : 'transparent', color: '#fff',
border: `1px solid ${hov ? 'rgba(255,255,255,.4)' : 'rgba(255,255,255,.22)'}`
},
secondary: {
background: hov ? 'var(--surface-2)' : 'var(--surface)', color: 'var(--fg1)',
border: '1px solid var(--border-strong)'
},
ghost: {
background: 'transparent', color: 'var(--brand-press)', border: '1px solid transparent'
}
};
const base = {
display: 'inline-flex', alignItems: 'center', justifyContent: 'center', gap: 9,
fontFamily: 'var(--font-body)', fontWeight: 600, fontSize: fs, lineHeight: 1,
borderRadius: 8, padding: pad, cursor: 'pointer', textDecoration: 'none', whiteSpace: 'nowrap',
transition: 'background .2s var(--ease), border-color .2s var(--ease), transform .12s var(--ease)',
transform: hov ? 'translateY(-1px)' : 'none',
...variants[variant], ...style
};
const inner = (
{icon && }
{children}
{iconRight && }
);
const handlers = { onMouseEnter: () => setHov(true), onMouseLeave: () => setHov(false) };
return href
? {inner}
: {inner} ;
}
// ---- Header ----------------------------------------------------------
function Header({ current }) {
const [scrolled, setScrolled] = React.useState(false);
const [open, setOpen] = React.useState(false);
React.useEffect(() => {
const onScroll = () => setScrolled(window.scrollY > 24);
onScroll();
window.addEventListener('scroll', onScroll);
return () => window.removeEventListener('scroll', onScroll);
}, []);
return (
);
}
// ---- Footer ----------------------------------------------------------
function Footer() {
const cols = [
{ h: 'Services', items: [['CCTV Systems', 'services.html'], ['Access Control', 'services.html'], ['24/7 Monitoring', 'services.html'], ['Security Assessments', 'services.html'], ['Intruder Alarms', 'services.html'], ['Fire Systems', 'services.html'], ['Smart Integration', 'services.html']] },
{ h: 'Company', items: [['About Fortify', 'about.html'], ['Our partners', 'about.html'], ['Contact', 'contact.html'], ['Get a quote', 'contact.html#quote']] },
{ h: 'Sectors', items: [['Retail & commercial', 'retail.html'], ['Hospitality', 'hospitality.html'], ['Offices', 'offices.html'], ['Multi-site', 'multi-site.html']] }
];
return (
Professional CCTV, access control and security assessments for businesses across Gibraltar — designed, installed and maintained by a team that's local and on call.
{cols.map(c => (
))}
© {new Date().getFullYear()} Fortify Security Systems Ltd, Gibraltar
);
}
// ---- SubHero (photographic page header for sub-pages) ----------------
function SubHero({ eyebrow, title, lead, children }) {
return (
{/* base grid texture (fallback) */}
{/* hero photograph */}
{/* legibility scrims — left dark → right clear */}
{eyebrow && {eyebrow} }
{title}
{lead && {lead}
}
{children}
);
}
// ---- CTABand (shared closing call-to-action) -------------------------
function CTABand({ eyebrow = 'BOOK A FREE ASSESSMENT', title = 'Ready to secure your premises?', body = "Tell us about your site and we'll arrange a visit. Locally based, fast to respond, no obligation." }) {
return (
Get a quote
{FY_CONTACT.email}
);
}
Object.assign(window, { Container, Eyebrow, Btn, Header, Footer, SubHero, CTABand, FY_NAV, FY_CONTACT });