// GSP — Alarmas (AX Home / Kit Home) page sections, in the canonical design system. function AlmReveal({ children, delay = 0, variant = 'up', style = {} }) { const ref = React.useRef(null); React.useEffect(() => { const el = ref.current; const ob = new IntersectionObserver((es) => es.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); }), { threshold: 0.12, rootMargin: '0px 0px -40px 0px' }); ob.observe(el); return () => ob.disconnect(); }, []); return
{children}
; } function ImgPlaceholder({ icon = 'home', label, className = '', style = {} }) { const Icon = window.Icon; return (
{label}
); } // ── HERO ── function AlmHero() { const Icon = window.Icon; const badges = [['wifi', 'Inalámbrico'], ['smartphone', 'Control por app'], ['zap', 'Respaldo de energía'], ['clock', 'Monitoreo 24/7']]; return (
GSP Kit Home · AX Home

Alarmas para tu hogar
y tu empresa

Sistema de alarma inalámbrico, fácil de usar y con control desde tu celular. Protección de alta calidad, sin obras y a un precio accesible.

{badges.map(([ic, lb]) => (
{lb}
))}
Descubrí más
); } window.AlmHero = AlmHero; // ── Isometric 3D house builder (procedural SVG) — lights up room-by-room ── function buildGspHouse(svg) { if (!svg || svg.dataset.built) return; svg.dataset.built = '1'; const NS = 'http://www.w3.org/2000/svg'; const ox = 265, oy = 72, ux = 20, uy = 10, uz = 16, wh = 2.8, wt = 0.35; const iso = (x, y, z) => [Math.round(ox + x * ux - y * ux), Math.round(oy + x * uy + y * uy - (z || 0) * uz)]; const pts = arr => arr.map(p => p[0] + ',' + p[1]).join(' '); const addEl = (par, tag, a) => { const el = document.createElementNS(NS, tag); for (const k in a) if (a.hasOwnProperty(k)) el.setAttribute(k, a[k]); par.appendChild(el); return el; }; const addPoly = (par, coords, fill, a) => { a = a || {}; a.points = pts(coords); if (fill) a.fill = fill; return addEl(par, 'polygon', a); }; const addG = (par, cls) => addEl(par, 'g', cls ? { 'class': cls } : {}); const drawBox = (par, bx, by, bw, bd, bh, tc, sc, ec) => { addPoly(par, [iso(bx, by + bd, 0), iso(bx + bw, by + bd, 0), iso(bx + bw, by + bd, bh), iso(bx, by + bd, bh)], sc); addPoly(par, [iso(bx + bw, by, 0), iso(bx + bw, by + bd, 0), iso(bx + bw, by + bd, bh), iso(bx + bw, by, bh)], ec); addPoly(par, [iso(bx, by, bh), iso(bx + bw, by, bh), iso(bx + bw, by + bd, bh), iso(bx, by + bd, bh)], tc); }; const drawWallS = (par, x1, x2, y, h) => { addPoly(par, [iso(x1, y, 0), iso(x2, y, 0), iso(x2, y, h), iso(x1, y, h)], '#252535'); addPoly(par, [iso(x1, y, h), iso(x2, y, h), iso(x2, y - wt, h), iso(x1, y - wt, h)], '#4a4a58'); }; const drawWallE = (par, y1, y2, x, h) => { addPoly(par, [iso(x, y1, 0), iso(x, y2, 0), iso(x, y2, h), iso(x, y1, h)], '#353548'); addPoly(par, [iso(x, y1, h), iso(x, y2, h), iso(x - wt, y2, h), iso(x - wt, y1, h)], '#4a4a58'); }; const rooms = [ { n: 'bedroom', c: [0, 0, 6, 5], f: '#c8ac80' }, { n: 'bathroom', c: [0, 5, 6, 10], f: '#9cc0d0' }, { n: 'living', c: [6, 0, 12, 5], f: '#c8ac80' }, { n: 'kitchen', c: [6, 5, 12, 10], f: '#d4c6a8' }, ]; const defs = svg.querySelector('defs'); const cp = addEl(defs, 'clipPath', { id: 'houseClip' }); addPoly(cp, [iso(0, 0), iso(12, 0), iso(12, 10), iso(0, 10)], null); const gF = addG(svg, 'floors'); rooms.forEach(r => { const c = r.c; addPoly(gF, [iso(c[0], c[1]), iso(c[2], c[1]), iso(c[2], c[3]), iso(c[0], c[3])], r.f); }); // furniture const gFn = addG(svg, 'furniture'); const gBR = addG(gFn); drawBox(gBR, 0.4, 0.5, 2.6, 3.8, 0.35, '#6a5540', '#5a4530', '#604b38'); drawBox(gBR, 0.6, 0.7, 2.2, 3.4, 0.5, '#c4a882', '#a08868', '#b49878'); drawBox(gBR, 0.9, 0.7, 1.6, 0.5, 0.55, '#d8c8a8', '#b8a888', '#c8b898'); drawBox(gBR, 3.5, 3.0, 2.0, 1.2, 0.65, '#7a6545', '#6a5535', '#705b40'); const gLR = addG(gFn); drawBox(gLR, 6.5, 0.3, 3.5, 0.4, 0.65, '#4a3555', '#3a2545', '#40294a'); drawBox(gLR, 6.5, 0.7, 3.5, 1.5, 0.45, '#5a4565', '#4a3555', '#503b5a'); drawBox(gLR, 7.5, 2.5, 2.0, 1.2, 0.3, '#7a6545', '#6a5535', '#705b40'); drawBox(gLR, 11.0, 0.3, 0.4, 2.5, 0.5, '#333', '#252525', '#2a2a2a'); drawBox(gLR, 11.05, 0.5, 0.12, 2.0, 1.1, '#222', '#1a1a1a', '#1e1e1e'); const gBA = addG(gFn); drawBox(gBA, 0.4, 5.5, 1.5, 3.5, 0.55, '#c0d0d8', '#a0b0b8', '#b0c0c8'); drawBox(gBA, 0.4, 9.0, 2.5, 0.6, 0.75, '#bbb', '#999', '#aaa'); drawBox(gBA, 4.0, 8.0, 1.2, 0.35, 0.5, '#e0e0e0', '#c8c8c8', '#d4d4d4'); const gKI = addG(gFn); drawBox(gKI, 6.4, 5.3, 5.0, 0.65, 0.85, '#8a8a8a', '#6a6a6a', '#7a7a7a'); drawBox(gKI, 10.8, 5.3, 0.7, 2.5, 0.85, '#8a8a8a', '#6a6a6a', '#7a7a7a'); drawBox(gKI, 8.5, 5.35, 1.2, 0.5, 0.87, '#90b0c0', '#7898a8', '#84a0b0'); drawBox(gKI, 7.5, 7.5, 2.0, 1.5, 0.6, '#7a6545', '#6a5535', '#705b40'); // interior glows (clipped) const gGL = addG(svg, 'room-glows'); gGL.setAttribute('clip-path', 'url(#houseClip)'); rooms.forEach(r => { const c = r.c, ctr = iso((c[0] + c[2]) / 2, (c[1] + c[3]) / 2); addEl(gGL, 'circle', { cx: ctr[0], cy: ctr[1], r: 100, fill: 'url(#interiorGlow)', 'class': 'room-glow rg-' + r.n }); }); // overlays const gOv = addG(svg, 'room-overlays'); rooms.forEach(r => { const c = r.c; addPoly(gOv, [iso(c[0], c[1]), iso(c[2], c[1]), iso(c[2], c[3]), iso(c[0], c[3])], '#080810', { 'class': 'room-overlay ro-' + r.n }); }); // walls const gW = addG(svg, 'walls'); drawWallS(gW, 0, 12, 0, wh); drawWallE(gW, 0, 10, 0, wh); drawWallS(gW, 0, 2, 5, wh); drawWallS(gW, 4, 6, 5, wh); drawWallS(gW, 6, 8, 5, wh); drawWallS(gW, 10, 12, 5, wh); drawWallE(gW, 0, 1.5, 6, wh); drawWallE(gW, 3.5, 5, 6, wh); drawWallE(gW, 5, 6.5, 6, wh); drawWallE(gW, 8.5, 10, 6, wh); drawWallS(gW, 0, 12, 10, wh); drawWallE(gW, 0, 7, 12, wh); drawWallE(gW, 9, 10, 12, wh); const gDoor = addG(gW, 'front-door'); addPoly(gDoor, [iso(12, 7, 0), iso(12, 9, 0), iso(12, 9, 2.2), iso(12, 7, 2.2)], '#5a4030'); const kn = iso(12, 8.3, 1.0); addEl(gDoor, 'circle', { cx: kn[0], cy: kn[1], r: 3, fill: '#c9a83a' }); // exterior protection aura const gExt = addG(svg, 'exterior-glow-group'); const hc = iso(6, 5); addEl(gExt, 'ellipse', { cx: hc[0], cy: hc[1], rx: 260, ry: 160, fill: 'url(#exteriorGlow)', 'class': 'exterior-glow', filter: 'url(#softGlow)' }); // security devices const gS = addG(svg, 'security-devices'); const cam = iso(12, 6.5, 2.2); const gCam = addG(gS, 'security-device'); addEl(gCam, 'rect', { x: cam[0] - 7, y: cam[1] - 4, width: 14, height: 9, rx: 2, fill: '#444' }); addEl(gCam, 'circle', { cx: cam[0], cy: cam[1], r: 3, fill: '#222' }); addEl(gCam, 'circle', { cx: cam[0] + 5, cy: cam[1] - 3, r: 1.5, fill: '#E71A21', 'class': 'led-blink', filter: 'url(#ledGlow)' }); const mot = iso(6, 5, 2.0); const gMot = addG(gS, 'security-device'); addEl(gMot, 'rect', { x: mot[0] - 5, y: mot[1] - 3, width: 10, height: 7, rx: 2, fill: '#ddd' }); addEl(gMot, 'circle', { cx: mot[0] + 3, cy: mot[1], r: 1.3, fill: '#34c171', 'class': 'led-blink', filter: 'url(#ledGlow)' }); } // ── COTIZADOR (3-step interactive quote, isometric house) ── function Cotizador() { const Icon = window.Icon; const [step, setStep] = React.useState(1); const [tipo, setTipo] = React.useState(''); const [localidad, setLocalidad] = React.useState(''); const [nombre, setNombre] = React.useState(''); const [tel, setTel] = React.useState(''); const [info, setInfo] = React.useState(''); const [sent, setSent] = React.useState(false); const [err, setErr] = React.useState(false); const [sending, setSending] = React.useState(false); const [hp, setHp] = React.useState(''); const [secs, setSecs] = React.useState(30); const [running, setRunning] = React.useState(false); const [elapsed, setElapsed] = React.useState(0); const svgRef = React.useRef(null); const startRef = React.useRef(null); const tsRef = React.useRef(null); const tsId = React.useRef(null); React.useEffect(() => { buildGspHouse(svgRef.current); }, []); React.useEffect(() => { if (step === 3 && window.GSPForms && tsRef.current && tsId.current == null) { window.GSPForms.renderTurnstile(tsRef.current).then((id) => { tsId.current = id; }); } }, [step]); React.useEffect(() => { if (!running || sent) return; if (secs <= 0) return; const t = setTimeout(() => setSecs(s => Math.max(0, s - 1)), 1000); return () => clearTimeout(t); }, [running, sent, secs]); const beginAt = (val) => { setTipo(val); if (!startRef.current) { startRef.current = Date.now(); setRunning(true); } setStep(2); }; const submit = (e) => { e.preventDefault(); if (sending) return; if (!nombre.trim() || !tel.trim()) return; setErr(false); setSending(true); const token = window.GSPForms ? window.GSPForms.getToken(tsId.current) : ''; window.GSPForms.submit({ formId: 'cotizacion-axhome', fields: { tipo, localidad, nombre, telefono: tel, info }, meta: { startedAt: startRef.current, hp, token }, }).then(() => { setElapsed(Math.round((Date.now() - (startRef.current || Date.now())) / 1000)); setRunning(false); setSending(false); setSent(true); }).catch((e2) => { console.warn('[Cotizador] envío falló:', e2 && e2.message); setSending(false); setErr(true); if (window.GSPForms) window.GSPForms.resetTurnstile(tsId.current); }); }; const houseState = sent ? 3 : step; const pct = sent ? 100 : (step === 1 ? 10 : step === 2 ? 40 : 75); const labels = ['Tu propiedad', 'Tu ubicación', 'Tus datos']; const timerDone = secs <= 0; return (

Cotizá tu alarma en 30″

3 pasos simples para proteger lo que más importa

{labels.map((l, i) => ( i + 1 || sent) ? ' done' : '')}>{l} ))}
{sent ? '✓' : (timerDone ? '—' : secs)} {sent ? 'enviado' : (timerDone ? <>¡Tomáte
tu tiempo! : <>segundos
para terminar)}
{sent ? (

¡Tu cotización está en camino!

Nos pondremos en contacto en breve.

{elapsed > 0 && elapsed <= 30 ? '¡Listo en ' + elapsed + ' segundos!' : 'Cotización enviada correctamente.'}

¿Querés hablar ahora?
) : step === 1 ? (

¿Es para tu casa o tu comercio?

{[['home', 'Casa', 'casa'], ['layers', 'Comercio', 'comercio']].map(([ic, lb, val]) => ( ))}
) : step === 2 ? (

¿Dónde se encuentra?

setLocalidad(e.target.value)} />
) : (

¿Cómo te contactamos?

setNombre(e.target.value)} /> setTel(e.target.value)} />