/* global React, Eyebrow, GlassCard, Icon, Btn, Light, Sticker */ const { useState: useStateBL, useEffect: useEffectBL, useMemo: useMemoBL } = React; const CATEGORIES = [ { key: 'all', label: 'Todos', color: '#F6F4F5' }, { key: 'compliance', label: 'Compliance', color: '#A335E7' }, { key: 'pentest', label: 'Pentesting', color: '#EC4D2A' }, { key: 'devsecops', label: 'DevSecOps', color: '#3551E7' }, { key: 'cloud', label: 'Cloud Security', color: '#35E7C7' }, { key: 'awareness', label: 'Awareness', color: '#FB881D' }, { key: 'opinion', label: 'Opinión', color: '#35E747' }, ]; const POSTS = [ { featured: true, cat: 'compliance', catLabel: 'Compliance', catColor: '#A335E7', title: 'ISO 27001 vs SOC 2: cuál certificar primero si vendés a EE.UU.', excerpt: 'Una decisión de timeline que define si cerrás el deal enterprise este trimestre o el próximo. Guía práctica para CTOs de SaaS argentinos que escalan al norte.', author: 'Brian Suarez', role: 'Co-founder', date: '28 Abr 2026', read: '12 min', badge: 'Guía completa', href: 'blog/iso-27001-vs-soc-2.html', }, { cat: 'pentest', catLabel: 'Pentesting', catColor: '#EC4D2A', title: 'Anatomía de un breach: cómo un parámetro mal validado costó USD 2.1M', excerpt: 'Write-up técnico de un engagement reciente — cómo encontramos la cadena de explotación y qué controles habrían cortado el ataque en cualquiera de los 4 pasos.', author: 'Brian Suarez', role: 'Co-founder', date: '15 Abr 2026', read: '9 min', href: 'blog/anatomia-de-un-breach.html', }, { cat: 'devsecops', catLabel: 'DevSecOps', catColor: '#3551E7', title: 'SAST que no rompe el pipeline: presupuesto de tiempo y false positives', excerpt: 'Cómo configurar Semgrep, Snyk o CodeQL sin sumar 20 minutos a cada PR ni inundar a los devs con alertas que ya saben.', author: 'Brian Suarez', role: 'Co-founder', date: '09 Abr 2026', read: '7 min', href: 'blog/sast-pipeline-ci-cd.html', }, { cat: 'cloud', catLabel: 'Cloud', catColor: '#35E7C7', title: 'AWS hardening en 14 controles que el auditor SOC 2 va a pedir', excerpt: 'CloudTrail, GuardDuty, Config, IAM Access Analyzer — el orden, el costo y qué dejar para el sprint 2.', author: 'Gonzalo De Simone', role: 'Co-founder', date: '19 Mar 2026', read: '11 min', href: 'blog/aws-hardening-soc2.html', }, { cat: 'compliance', catLabel: 'Compliance', catColor: '#A335E7', title: 'Anexo A.8: Asset Management sin morir en hojas de cálculo', excerpt: 'El control que más demora la primera certificación. Cómo Ariana lo automatiza tirando de tus inventarios cloud y endpoints existentes.', author: 'Brian Suarez', role: 'Co-founder', date: '06 Mar 2026', read: '7 min', href: 'blog/anexo-a8-asset-management.html', }, { cat: 'awareness', catLabel: 'Awareness', catColor: '#FB881D', title: 'Phishing simulado: por qué el 38% nunca debería ser tu KPI', excerpt: 'Click-rates altos no significan que el programa falle. Datos de 14 campañas en fintechs argentinas y qué métricas sí mover.', author: 'Gonzalo De Simone', role: 'Co-founder', date: '27 Feb 2026', read: '6 min', href: 'blog/phishing-simulado-kpi.html', }, { cat: 'pentest', catLabel: 'Pentesting', catColor: '#EC4D2A', title: 'API security: los 6 hallazgos que aparecen en cada engagement de fintech', excerpt: 'BOLA, mass assignment, JWT misconfig — el top de OWASP API que seguimos viendo en 2026 y cómo prevenirlos en CI.', author: 'Brian Suarez', role: 'Co-founder', date: '16 Feb 2026', read: '8 min', href: 'blog/api-security-fintech.html', }, { cat: 'opinion', catLabel: 'Opinión', catColor: '#35E747', title: 'Por qué dejamos de vender retainers de seguridad', excerpt: 'La estructura comercial vieja no sirve para empresas que escalan. Lo que aprendimos al cambiar a packs por outcome.', author: 'Brian Suarez', role: 'Co-founder', date: '02 Feb 2026', read: '5 min', href: 'blog/retainers-vs-outcomes.html', }, { cat: 'devsecops', catLabel: 'DevSecOps', catColor: '#3551E7', title: 'Threat modeling en 90 minutos: el formato que sí adoptan los devs', excerpt: 'STRIDE simplificado para una sesión rápida con el equipo de producto — incluye el template Miro que usamos en cada feature crítica.', author: 'Gonzalo De Simone', role: 'Co-founder', date: '16 Ene 2026', read: '6 min', href: 'blog/threat-modeling-90-minutos.html', }, ]; const PostCard = ({ post, featured }) => { const [hover, setHover] = useStateBL(false); if (featured) { return ( setHover(true)} onMouseLeave={() => setHover(false)} style={{ textDecoration: 'none', color: 'inherit', display: 'block' }}>
{/* Visual side */}
{/* concentric rings */}
{/* sticker decoration */}
FEATURED · {post.badge}
{/* Copy side */}
{post.catLabel}

{post.title}

{post.excerpt}

{post.author.split(' ').map(w => w[0]).slice(0,2).join('')}
{post.author}
{post.role}
{post.date} · {post.read}
); } return ( setHover(true)} onMouseLeave={() => setHover(false)} style={{ textDecoration: 'none', color: 'inherit', display: 'block' }}> {/* visual block */}
{/* decorative grid */}
{/* glyph */}
{post.catLabel.charAt(0)}
{post.catLabel}

{post.title}

{post.excerpt}

{post.author.split(' ').map(w => w[0]).slice(0,2).join('')}
{post.author}
{post.read}
); }; const BlogList = () => { const [activeCat, setActiveCat] = useStateBL('all'); const [search, setSearch] = useStateBL(''); const [visible, setVisible] = useStateBL(8); useEffectBL(() => { const onSearch = (e) => { setSearch(e.detail || ''); setVisible(8); }; window.addEventListener('brotek-search', onSearch); return () => window.removeEventListener('brotek-search', onSearch); }, []); const filtered = useMemoBL(() => { const q = search.trim().toLowerCase(); return POSTS.filter(p => { if (activeCat !== 'all' && p.cat !== activeCat) return false; if (!q) return true; return (p.title + ' ' + p.excerpt + ' ' + p.catLabel).toLowerCase().includes(q); }); }, [activeCat, search]); const featured = filtered.find(p => p.featured) || filtered[0]; const rest = filtered.filter(p => p !== featured).slice(0, visible); return (
{/* Filter chips */}
{CATEGORIES.map(c => { const sel = c.key === activeCat; return ( ); })}
{filtered.length} {filtered.length === 1 ? 'artículo' : 'artículos'}
{/* Empty state */} {filtered.length === 0 && (

No encontramos resultados

Probá otra categoría o quitá la búsqueda.

)} {/* Featured */} {featured && (
)} {/* Grid */} {rest.length > 0 && (
{rest.map((p, i) => )}
)} {/* Load more */} {rest.length < filtered.filter(p => p !== featured).length && (
setVisible(v => v + 6)}>Cargar más artículos
)}
); }; window.BlogList = BlogList;