{"id":65,"date":"2026-04-19T21:03:56","date_gmt":"2026-04-19T20:03:56","guid":{"rendered":"https:\/\/ocode360pulse.com\/index.php\/blog\/"},"modified":"2026-05-08T10:50:41","modified_gmt":"2026-05-08T09:50:41","slug":"blog","status":"publish","type":"page","link":"https:\/\/ocode360pulse.com\/index.php\/blog\/","title":{"rendered":"Blog Post"},"content":{"rendered":"\n<!DOCTYPE html>\n<html lang=\"en\" class=\"scroll-smooth\">\n<head>\n  <meta charset=\"UTF-8\" \/>\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" \/>\n  <title>Blog \u2014 oCode360Pulse<\/title>\n  <script src=\"https:\/\/cdn.tailwindcss.com\"><\/script>\n  <link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\" \/>\n  <link href=\"https:\/\/fonts.googleapis.com\/css2?family=Open+Sans:wght@300;400;500;600;700;800&#038;display=swap\" rel=\"stylesheet\" \/>\n  <style>\n    :root {\n      --card: #f7f8f8;\n      --ring: #1da1f2;\n      --border: #e1eaef;\n      --primary: #1e9df1;\n      --background: #ffffff;\n      --foreground: #0f1419;\n      --muted-foreground: #536471;\n      --font-sans: 'Open Sans', sans-serif;\n    }\n    * { box-sizing: border-box; margin: 0; padding: 0; }\n    body { font-family: var(--font-sans); background: var(--background); color: var(--foreground); }\n\n    .sr { opacity: 0; transform: translateY(28px); transition: opacity 0.75s ease, transform 0.75s ease; }\n    .sr.visible { opacity: 1; transform: translateY(0); }\n\n    .nav-link { position: relative; }\n    .nav-link::after { content: ''; position: absolute; bottom: -2px; left: 0; width: 0; height: 2px; background: #1e9df1; transition: width 0.25s ease; }\n    .nav-link:hover::after { width: 100%; }\n    .nav-link.active::after { width: 100%; }\n\n    \/* Blog card *\/\n    .blog-card {\n      transition: transform 0.25s ease, box-shadow 0.25s ease, border-color 0.25s ease;\n      border: 1px solid #e1eaef;\n    }\n    .blog-card:hover {\n      transform: translateY(-5px);\n      box-shadow: 0 16px 40px rgba(30,157,241,0.1);\n      border-color: rgba(30,157,241,0.25);\n    }\n\n    \/* Filter pill *\/\n    .filter-pill {\n      cursor: pointer;\n      transition: all 0.2s ease;\n      border: 1.5px solid #e1eaef;\n      font-size: 0.8125rem;\n      font-weight: 600;\n      padding: 0.45rem 1.1rem;\n      border-radius: 9999px;\n      color: #536471;\n      background: white;\n    }\n    .filter-pill:hover { border-color: #1e9df1; color: #1e9df1; }\n    .filter-pill.active { background: #1e9df1; border-color: #1e9df1; color: white; }\n\n    \/* Tag badge *\/\n    .tag-short    { background: rgba(99,102,241,0.08); color: #6366f1; }\n    .tag-research { background: rgba(30,157,241,0.08); color: #1e9df1; }\n\n    \/* Featured card image area *\/\n    .card-image {\n      height: 200px;\n      background-size: cover;\n      background-position: center;\n      border-radius: 0.75rem 0.75rem 0 0;\n    }\n\n    \/* Read time dot *\/\n    .dot { display: inline-block; width: 3px; height: 3px; border-radius: 50%; background: #94a3b8; vertical-align: middle; margin: 0 6px; }\n\n    @keyframes pathAnim {\n      0%   { stroke-dashoffset: 2000; opacity: 0.3; }\n      100% { stroke-dashoffset: 0; opacity: 0.3; }\n    }\n    .bg-path { stroke-dasharray: 2000; stroke-dashoffset: 2000; animation: pathAnim 22s linear infinite; }\n\n    \/* Hide\/show for filter *\/\n    .post-card { display: flex; }\n    .post-card.hidden-post { display: none !important; }\n  <\/style>\n<\/head>\n<body>\n\n<!-- \u2500\u2500 NAVBAR \u2500\u2500 -->\n<nav id=\"navbar\" class=\"fixed top-0 left-0 right-0 z-50 border-b border-gray-100\/60 bg-white\/90\" style=\"backdrop-filter:blur(12px)\">\n  <div class=\"container mx-auto flex items-center justify-between px-6 py-3 max-w-7xl\">\n    <a href=\"ocode360pulse.html\" class=\"flex items-center gap-2\">\n      <div class=\"w-6 h-6 rounded-lg flex items-center justify-center\" style=\"background:#1e9df1\">\n        <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" stroke-width=\"2.5\" stroke-linecap=\"round\">\n          <polyline points=\"22 12 18 12 15 21 9 3 6 12 2 12\"\/>\n        <\/svg>\n      <\/div>\n      <span class=\"font-bold text-sm tracking-tight\" style=\"color:#0f1419\">oCode360<span style=\"color:#1e9df1\">Pulse<\/span><\/span>\n    <\/a>\n\n    <div class=\"hidden md:flex items-center gap-7 text-sm font-medium\" style=\"color:#536471\">\n      <a href=\"ocode360pulse.html#features\"     class=\"nav-link hover:text-gray-900 transition-colors\">Features<\/a>\n      <a href=\"ocode360pulse.html#services\"     class=\"nav-link hover:text-gray-900 transition-colors\">Services<\/a>\n      <a href=\"ocode360pulse.html#testimonials\" class=\"nav-link hover:text-gray-900 transition-colors\">Testimonials<\/a>\n      <a href=\"ocode360pulse.html#team\"         class=\"nav-link hover:text-gray-900 transition-colors\">Team<\/a>\n      <a href=\"ocode360pulse.html#faq\"          class=\"nav-link hover:text-gray-900 transition-colors\">FAQ<\/a>\n      <a href=\"ocode360pulse-blog.html\"         class=\"nav-link active\" style=\"color:#1e9df1\">Blog<\/a>\n      <a href=\"ocode360pulse-contact.html\"      class=\"nav-link hover:text-gray-900 transition-colors\">Contact<\/a>\n    <\/div>\n\n    <div class=\"flex items-center gap-3\">\n      <a href=\"#\" class=\"hidden md:block text-sm font-medium px-4 py-2 rounded-lg transition-colors hover:bg-gray-50\" style=\"color:#536471\">Sign In<\/a>\n      <a href=\"ocode360pulse-contact.html\" class=\"text-sm font-semibold px-5 py-2 rounded-lg text-white transition-all hover:opacity-90 hover:-translate-y-0.5\" style=\"background:#1e9df1; box-shadow:0 4px 14px rgba(30,157,241,0.35)\">Get Started<\/a>\n      <button id=\"mob-btn\" class=\"md:hidden p-2 rounded-lg hover:bg-gray-100\" onclick=\"document.getElementById('mob-menu').classList.toggle('hidden')\">\n        <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\"><line x1=\"3\" y1=\"6\" x2=\"21\" y2=\"6\"\/><line x1=\"3\" y1=\"12\" x2=\"21\" y2=\"12\"\/><line x1=\"3\" y1=\"18\" x2=\"21\" y2=\"18\"\/><\/svg>\n      <\/button>\n    <\/div>\n  <\/div>\n  <div id=\"mob-menu\" class=\"hidden md:hidden border-t\" style=\"background:white\">\n    <div class=\"flex flex-col px-6 py-4 gap-4 text-sm font-medium\" style=\"color:#536471\">\n      <a href=\"ocode360pulse.html#features\"     onclick=\"document.getElementById('mob-menu').classList.add('hidden')\">Features<\/a>\n      <a href=\"ocode360pulse.html#services\"     onclick=\"document.getElementById('mob-menu').classList.add('hidden')\">Services<\/a>\n      <a href=\"ocode360pulse.html#testimonials\" onclick=\"document.getElementById('mob-menu').classList.add('hidden')\">Testimonials<\/a>\n      <a href=\"ocode360pulse.html#team\"         onclick=\"document.getElementById('mob-menu').classList.add('hidden')\">Team<\/a>\n      <a href=\"ocode360pulse.html#faq\"          onclick=\"document.getElementById('mob-menu').classList.add('hidden')\">FAQ<\/a>\n      <a href=\"ocode360pulse-blog.html\"         style=\"color:#1e9df1\">Blog<\/a>\n      <a href=\"ocode360pulse-contact.html\"      onclick=\"document.getElementById('mob-menu').classList.add('hidden')\">Contact<\/a>\n    <\/div>\n  <\/div>\n<\/nav>\n\n\n<!-- \u2500\u2500 PAGE HERO \u2500\u2500 -->\n<section class=\"pt-32 pb-14 relative overflow-hidden\" style=\"background:#f7f9fa\">\n  <div class=\"absolute inset-0 pointer-events-none\">\n    <svg class=\"w-full h-full\" viewBox=\"0 0 800 300\" fill=\"none\" preserveAspectRatio=\"xMidYMid slice\">\n      <path class=\"bg-path\" d=\"M-100 80 C200 80 400 220 900 120\" stroke=\"#1e9df1\" stroke-width=\"0.5\" stroke-opacity=\"0.12\" style=\"animation-delay:0s\"\/>\n      <path class=\"bg-path\" d=\"M-100 160 C200 120 500 260 900 200\" stroke=\"#6366f1\" stroke-width=\"0.4\" stroke-opacity=\"0.08\" style=\"animation-delay:-8s\"\/>\n    <\/svg>\n  <\/div>\n\n  <div class=\"relative z-10 container mx-auto px-4 max-w-4xl text-center\">\n    <div class=\"sr visible inline-flex items-center gap-2 px-4 py-1.5 rounded-full border mb-6\" style=\"background:rgba(30,157,241,0.06);border-color:rgba(30,157,241,0.2)\">\n      <svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"#1e9df1\" stroke-width=\"2\"><path d=\"M12 20h9\"\/><path d=\"M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z\"\/><\/svg>\n      <span class=\"text-sm font-medium\" style=\"color:#1e9df1\">Developer Intelligence Blog<\/span>\n    <\/div>\n    <h1 class=\"sr visible text-4xl md:text-5xl lg:text-6xl font-bold tracking-tight mb-4\" style=\"color:#0f1419\">\n      Insights &amp; <span style=\"color:#1e9df1\">Research<\/span>\n    <\/h1>\n    <p class=\"sr visible text-base md:text-lg max-w-xl mx-auto\" style=\"color:#536471;line-height:1.7\">\n      Quick tips, deep dives, and engineering intelligence \u2014 from the oCode360 team.\n    <\/p>\n  <\/div>\n<\/section>\n\n\n<!-- \u2500\u2500 FILTER BAR + POST GRID \u2500\u2500 -->\n<section class=\"py-14 md:py-20\" style=\"background:white\">\n  <div class=\"container mx-auto px-4 max-w-6xl\">\n\n    <!-- Filter controls -->\n    <div class=\"sr flex flex-wrap items-center gap-3 mb-12\">\n      <span class=\"text-sm font-medium mr-1\" style=\"color:#536471\">Filter:<\/span>\n      <button class=\"filter-pill active\" data-filter=\"all\"      onclick=\"setFilter('all',this)\">All Posts<\/button>\n      <button class=\"filter-pill\"        data-filter=\"short\"    onclick=\"setFilter('short',this)\">\n        <span class=\"inline-flex items-center gap-1.5\">\n          <span class=\"w-2 h-2 rounded-full\" style=\"background:#6366f1\"><\/span>\n          Short Post\n        <\/span>\n      <\/button>\n      <button class=\"filter-pill\"        data-filter=\"research\" onclick=\"setFilter('research',this)\">\n        <span class=\"inline-flex items-center gap-1.5\">\n          <span class=\"w-2 h-2 rounded-full\" style=\"background:#1e9df1\"><\/span>\n          Long Research\n        <\/span>\n      <\/button>\n      <!-- Live count -->\n      <span id=\"post-count\" class=\"ml-auto text-xs font-medium\" style=\"color:#94a3b8\"><\/span>\n    <\/div>\n\n    <!-- Post grid -->\n    <div id=\"post-grid\" class=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6\"><\/div>\n\n    <!-- Empty state -->\n    <div id=\"empty-state\" class=\"hidden text-center py-20\">\n      <p class=\"text-lg font-medium mb-2\" style=\"color:#0f1419\">No posts yet in this category<\/p>\n      <p class=\"text-sm\" style=\"color:#536471\">Check back soon \u2014 we publish new content every week.<\/p>\n    <\/div>\n\n  <\/div>\n<\/section>\n\n\n<!-- \u2500\u2500 NEWSLETTER CTA \u2500\u2500 -->\n<section class=\"py-16 md:py-24\" style=\"background:#f7f9fa\">\n  <div class=\"container mx-auto px-4 max-w-3xl text-center\">\n    <div class=\"sr rounded-2xl p-10 md:p-14\" style=\"background:#0f1419\">\n      <h2 class=\"text-2xl md:text-3xl font-bold mb-3\" style=\"color:white\">Never miss a post<\/h2>\n      <p class=\"text-sm mb-8\" style=\"color:rgba(255,255,255,0.5)\">Join 2,000+ engineers who get our weekly developer intelligence digest.<\/p>\n      <form class=\"flex gap-3 flex-col sm:flex-row justify-center max-w-md mx-auto\" onsubmit=\"subscribeNewsletter(event)\">\n        <input type=\"email\" required placeholder=\"you@company.com\"\n          class=\"flex-1 px-4 py-2.5 rounded-lg text-sm border-0 outline-none\"\n          style=\"background:rgba(255,255,255,0.08);color:white;border:1.5px solid rgba(255,255,255,0.12);\" \/>\n        <button type=\"submit\" id=\"sub-btn\"\n          class=\"px-5 py-2.5 rounded-lg text-sm font-semibold text-white transition-all hover:opacity-90\"\n          style=\"background:#1e9df1;white-space:nowrap\">\n          Subscribe\n        <\/button>\n      <\/form>\n      <p id=\"sub-success\" class=\"hidden mt-4 text-sm\" style=\"color:rgba(30,157,241,0.85)\">You&#8217;re in! Expect great content in your inbox.<\/p>\n    <\/div>\n  <\/div>\n<\/section>\n\n\n<!-- \u2500\u2500 FOOTER \u2500\u2500 -->\n<footer style=\"background:#030303;color:rgba(255,255,255,0.45)\" class=\"py-12 px-6\">\n  <div class=\"max-w-6xl mx-auto flex flex-col md:flex-row items-center justify-between gap-6\">\n    <div class=\"flex items-center gap-2\">\n      <div class=\"w-6 h-6 rounded-lg flex items-center justify-center\" style=\"background:#1e9df1\">\n        <svg width=\"13\" height=\"13\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"white\" stroke-width=\"2.5\" stroke-linecap=\"round\"><polyline points=\"22 12 18 12 15 21 9 3 6 12 2 12\"\/><\/svg>\n      <\/div>\n      <span class=\"font-bold text-base\" style=\"color:rgba(255,255,255,0.85)\">oCode360<span style=\"color:#1e9df1\">Pulse<\/span><\/span>\n    <\/div>\n    <p class=\"text-xs text-center\">\u00a9 2026 oCode360. All rights reserved. Built with \u2665 in Cape Town.<\/p>\n    <div class=\"flex gap-5 text-xs\">\n      <a href=\"#\" class=\"hover:text-white transition-colors\">Privacy<\/a>\n      <a href=\"#\" class=\"hover:text-white transition-colors\">Terms<\/a>\n      <a href=\"ocode360pulse-blog.html\" class=\"hover:text-white transition-colors\" style=\"color:rgba(255,255,255,0.7)\">Blog<\/a>\n      <a href=\"ocode360pulse-contact.html\" class=\"hover:text-white transition-colors\">Contact<\/a>\n    <\/div>\n  <\/div>\n<\/footer>\n\n\n<script>\n\/\/ \u2500\u2500 WordPress REST API \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst COVERS = [\n  'https:\/\/images.unsplash.com\/photo-1555949963-aa79dcee981c?w=600&auto=format&fit=crop&q=60',\n  'https:\/\/images.unsplash.com\/photo-1551288049-bebda4e38f71?w=600&auto=format&fit=crop&q=60',\n  'https:\/\/images.unsplash.com\/photo-1461749280684-dccba630e2f6?w=600&auto=format&fit=crop&q=60',\n  'https:\/\/images.unsplash.com\/photo-1518432031352-d6fc5c10da5a?w=600&auto=format&fit=crop&q=60',\n  'https:\/\/images.unsplash.com\/photo-1522202176988-66273c2fd55f?w=600&auto=format&fit=crop&q=60',\n  'https:\/\/images.unsplash.com\/photo-1563013544-824ae1b704d3?w=600&auto=format&fit=crop&q=60',\n  'https:\/\/images.unsplash.com\/photo-1460925895917-afdab827c52f?w=600&auto=format&fit=crop&q=60',\n  'https:\/\/images.unsplash.com\/photo-1542744173-8e7e53415bb0?w=600&auto=format&fit=crop&q=60',\n];\n\nfunction wpToPost(p, type) {\n  const text       = (p.content?.rendered || '').replace(\/<[^>]+>\/g, '');\n  const words      = text.split(\/\\s+\/).filter(Boolean).length;\n  const readMin    = Math.max(1, Math.round(words \/ 200));\n  const rawExcerpt = (p.excerpt?.rendered || '').replace(\/<[^>]+>\/g, '').trim();\n  const excerpt    = rawExcerpt.length > 160 ? rawExcerpt.slice(0, 157) + '\u2026'\n                   : rawExcerpt || text.slice(0, 157) + '\u2026';\n  const date       = new Date(p.date).toLocaleDateString('en-ZA', { day: 'numeric', month: 'short', year: 'numeric' });\n  return {\n    type,\n    title:   (p.title?.rendered || 'Untitled').replace(\/\\s*\\|\\s*oCode360 Pulse$\/, ''),\n    excerpt,\n    author:  'oCode360',\n    avatar:  'https:\/\/i.pravatar.cc\/100?img=12',\n    date,\n    _date:   p.date,\n    readTime: `${readMin} min read`,\n    cover:   COVERS[p.id % COVERS.length],\n    tags:    [type === 'short' ? 'Quick Insights' : 'In-Depth Reads'],\n    link:    p.link,\n  };\n}\n\nlet posts = [];\nlet activeFilter = 'all';\n\nasync function loadPosts() {\n  document.getElementById('post-grid').innerHTML =\n    '<p class=\"col-span-3 text-center py-10 text-sm\" style=\"color:#94a3b8\">Loading posts\u2026<\/p>';\n  const base = window.location.origin;\n  const [short, research] = await Promise.all([\n    fetch(`${base}\/wp-json\/wp\/v2\/posts?categories=4&per_page=100&_fields=id,title,excerpt,date,link,content`)\n      .then(r => r.json()).catch(() => []),\n    fetch(`${base}\/wp-json\/wp\/v2\/posts?categories=5&per_page=100&_fields=id,title,excerpt,date,link,content`)\n      .then(r => r.json()).catch(() => []),\n  ]);\n  posts = [\n    ...short.map(p => wpToPost(p, 'short')),\n    ...research.map(p => wpToPost(p, 'research')),\n  ].sort((a, b) => new Date(b._date) - new Date(a._date));\n  renderPosts(activeFilter);\n}\n\n\/\/ \u2500\u2500 REMOVE old hardcoded posts array placeholder \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst _old_posts = [\n  {\n    type: 'short',\n    title: '5 Quick Wins for Faster CI\/CD Pipelines',\n    excerpt: 'Cut your build times in half with these five pipeline optimisations \u2014 each takes under 30 minutes to implement and delivers immediate results.',\n    author: 'Riana Botha',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=49',\n    date: '12 Apr 2026',\n    readTime: '4 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1555949963-aa79dcee981c?w=600&auto=format&fit=crop&q=60',\n    tags: ['CI\/CD', 'DevOps'],\n  },\n  {\n    type: 'short',\n    title: 'Why DORA Metrics Matter for Small Teams',\n    excerpt: 'Think DORA is only for big enterprise shops? Think again. Here\\'s how a 4-person team used deployment frequency to double their release velocity.',\n    author: 'Mpho Khumalo',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=22',\n    date: '8 Apr 2026',\n    readTime: '5 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1551288049-bebda4e38f71?w=600&auto=format&fit=crop&q=60',\n    tags: ['DORA', 'Metrics'],\n  },\n  {\n    type: 'short',\n    title: 'Claude AI in Your Dev Workflow: A Quick Start',\n    excerpt: 'Three ways to wire Claude into your daily engineering workflow today \u2014 PR summaries, security triage, and automated runbook generation.',\n    author: 'Thabo Sithole',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=33',\n    date: '3 Apr 2026',\n    readTime: '6 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1461749280684-dccba630e2f6?w=600&auto=format&fit=crop&q=60',\n    tags: ['AI', 'Claude'],\n  },\n  {\n    type: 'short',\n    title: 'Git Hooks That Actually Save Your Team Time',\n    excerpt: 'Pre-commit, pre-push, and commit-msg hooks your whole team will thank you for. Includes a ready-to-paste shell script.',\n    author: 'Dylan Strauss',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=7',\n    date: '27 Mar 2026',\n    readTime: '3 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1518432031352-d6fc5c10da5a?w=600&auto=format&fit=crop&q=60',\n    tags: ['Git', 'Tooling'],\n  },\n  {\n    type: 'research',\n    title: 'The State of Developer Intelligence: A 2026 Deep Dive',\n    excerpt: 'We surveyed 1,200 engineering teams across Africa, Europe, and North America. Here\\'s what separates high-performing orgs from the rest \u2014 and it\\'s not headcount.',\n    author: 'Jacko van Wyk',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=12',\n    date: '10 Apr 2026',\n    readTime: '22 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1522202176988-66273c2fd55f?w=600&auto=format&fit=crop&q=60',\n    tags: ['Research', 'Industry Report'],\n  },\n  {\n    type: 'research',\n    title: 'Security Scanning in Modern DevOps: A Comprehensive Analysis',\n    excerpt: 'An exhaustive breakdown of SAST, DAST, SCA, and container scanning across 14 tools \u2014 with benchmarks, false-positive rates, and integration complexity scores.',\n    author: 'Thabo Sithole',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=33',\n    date: '1 Apr 2026',\n    readTime: '28 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1563013544-824ae1b704d3?w=600&auto=format&fit=crop&q=60',\n    tags: ['Security', 'Research'],\n  },\n  {\n    type: 'research',\n    title: 'DORA Metrics: Research, Benchmarks & African Engineering Teams',\n    excerpt: 'The most comprehensive study of DORA metrics applied to African tech teams. Includes median benchmarks, outlier patterns, and a framework for improvement.',\n    author: 'Carla Ferreira',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=44',\n    date: '20 Mar 2026',\n    readTime: '19 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1460925895917-afdab827c52f?w=600&auto=format&fit=crop&q=60',\n    tags: ['DORA', 'Research', 'Africa'],\n  },\n  {\n    type: 'short',\n    title: 'Monitoring Your Microservices Without Losing Your Mind',\n    excerpt: 'The minimal viable observability stack for teams who don\\'t want to manage a full Datadog bill. Three tools, one config file, zero drama.',\n    author: 'Mpho Khumalo',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=22',\n    date: '15 Mar 2026',\n    readTime: '7 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1517245386807-bb43f82c33c4?w=600&auto=format&fit=crop&q=60',\n    tags: ['Monitoring', 'Microservices'],\n  },\n  {\n    type: 'research',\n    title: 'AI-Assisted Code Review: Six Months of Data from 80 Teams',\n    excerpt: 'We ran a longitudinal study on AI-assisted vs human-only code review cycles. The results on bug escape rates, review latency, and developer experience are revealing.',\n    author: 'Jacko van Wyk',\n    avatar: 'https:\/\/i.pravatar.cc\/100?img=12',\n    date: '5 Mar 2026',\n    readTime: '32 min read',\n    cover: 'https:\/\/images.unsplash.com\/photo-1542744173-8e7e53415bb0?w=600&auto=format&fit=crop&q=60',\n    tags: ['AI', 'Research', 'Code Review'],\n  },\n];\n\n\/\/ \u2500\u2500 Render \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction renderPosts(filter) {\n  const grid    = document.getElementById('post-grid');\n  const empty   = document.getElementById('empty-state');\n  const countEl = document.getElementById('post-count');\n\n  const visible = filter === 'all' ? posts : posts.filter(p => p.type === filter);\n  countEl.textContent = `${visible.length} post${visible.length !== 1 ? 's' : ''}`;\n\n  if (visible.length === 0) {\n    grid.innerHTML = '';\n    empty.classList.remove('hidden');\n    return;\n  }\n  empty.classList.add('hidden');\n\n  grid.innerHTML = visible.map((p, i) => {\n    const tagClass = p.type === 'short' ? 'tag-short' : 'tag-research';\n    const tagLabel = p.type === 'short' ? 'Short Post' : 'Long Research';\n    return `\n    <article class=\"post-card flex-col bg-white rounded-xl overflow-hidden blog-card\"\n      data-type=\"${p.type}\" style=\"animation-delay:${i * 0.05}s\">\n      <div class=\"card-image flex-shrink-0\" style=\"background-image:url('${p.cover}')\"><\/div>\n      <div class=\"flex flex-col flex-1 p-5\">\n        <div class=\"flex flex-wrap items-center gap-2 mb-3\">\n          <span class=\"text-xs font-semibold px-2.5 py-0.5 rounded-full ${tagClass}\">${tagLabel}<\/span>\n          ${p.tags.map(t => `<span class=\"text-xs px-2 py-0.5 rounded-full\" style=\"background:#f7f9fa;color:#536471;border:1px solid #e1eaef\">${t}<\/span>`).join('')}\n        <\/div>\n        <h2 class=\"font-bold text-base leading-snug mb-2 flex-1\" style=\"color:#0f1419\">${p.title}<\/h2>\n        <p class=\"text-xs leading-relaxed mb-4\" style=\"color:#536471\">${p.excerpt}<\/p>\n        <div class=\"flex items-center gap-2 pt-4 border-t\" style=\"border-color:#e1eaef\">\n          <img decoding=\"async\" src=\"${p.avatar}\" alt=\"${p.author}\" class=\"w-7 h-7 rounded-full border flex-shrink-0\" style=\"border-color:#e1eaef\" \/>\n          <div class=\"flex-1 min-w-0\">\n            <p class=\"text-xs font-semibold truncate\" style=\"color:#0f1419\">${p.author}<\/p>\n            <p class=\"text-xs\" style=\"color:#94a3b8\">${p.date}<span class=\"dot\"><\/span>${p.readTime}<\/p>\n          <\/div>\n          <a href=\"${p.link}\" target=\"_blank\" rel=\"noopener\"\n            class=\"flex-shrink-0 text-xs font-semibold px-3 py-1.5 rounded-lg transition-all hover:opacity-80\"\n            style=\"background:#1e9df1;color:white\">Read \u2192<\/a>\n        <\/div>\n      <\/div>\n    <\/article>`;\n  }).join('');\n}\n\n\/\/ \u2500\u2500 Filter logic \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction setFilter(filter, btn) {\n  activeFilter = filter;\n  document.querySelectorAll('.filter-pill').forEach(p => p.classList.remove('active'));\n  btn.classList.add('active');\n  renderPosts(filter);\n}\n\n\/\/ \u2500\u2500 Newsletter \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nfunction subscribeNewsletter(e) {\n  e.preventDefault();\n  const btn = document.getElementById('sub-btn');\n  btn.textContent = 'Subscribing\u2026';\n  btn.disabled = true;\n  setTimeout(() => {\n    btn.style.display = 'none';\n    document.getElementById('sub-success').classList.remove('hidden');\n  }, 900);\n}\n\n\/\/ \u2500\u2500 Init \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nloadPosts();\n\n\/\/ Scroll reveal\nconst observer = new IntersectionObserver(entries => {\n  entries.forEach(e => { if (e.isIntersecting) e.target.classList.add('visible'); });\n}, { threshold: 0.08 });\ndocument.querySelectorAll('.sr').forEach(el => observer.observe(el));\n\n\/\/ Navbar shadow\nwindow.addEventListener('scroll', () => {\n  const nav = document.getElementById('navbar');\n  nav.style.boxShadow = window.scrollY > 10 ? '0 1px 20px rgba(0,0,0,0.06)' : 'none';\n});\n<\/script>\n<\/body>\n<\/html>\n\n","protected":false},"excerpt":{"rendered":"<p>Blog \u2014 oCode360Pulse oCode360Pulse Features Services Testimonials Team FAQ Blog Contact Sign In Get Started Features Services Testimonials Team FAQ Blog Contact Developer Intelligence Blog Insights &amp; Research Quick tips, deep dives, and engineering intelligence \u2014 from the oCode360 team. Filter: All Posts Short Post Long Research No posts yet in this category Check back [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"fullwidth.php","meta":{"footnotes":""},"class_list":["post-65","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ocode360pulse.com\/index.php\/wp-json\/wp\/v2\/pages\/65","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ocode360pulse.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ocode360pulse.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ocode360pulse.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ocode360pulse.com\/index.php\/wp-json\/wp\/v2\/comments?post=65"}],"version-history":[{"count":8,"href":"https:\/\/ocode360pulse.com\/index.php\/wp-json\/wp\/v2\/pages\/65\/revisions"}],"predecessor-version":[{"id":494,"href":"https:\/\/ocode360pulse.com\/index.php\/wp-json\/wp\/v2\/pages\/65\/revisions\/494"}],"wp:attachment":[{"href":"https:\/\/ocode360pulse.com\/index.php\/wp-json\/wp\/v2\/media?parent=65"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}