{"id":387,"date":"2026-07-27T20:03:04","date_gmt":"2026-07-27T20:03:04","guid":{"rendered":"https:\/\/monichron.co.za\/?page_id=387"},"modified":"2026-08-04T07:38:20","modified_gmt":"2026-08-04T07:38:20","slug":"services-2","status":"publish","type":"page","link":"https:\/\/monichron.co.za\/index.php\/services-2\/","title":{"rendered":"Services-2"},"content":{"rendered":"\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Our Services<\/title>\n<link rel=\"preconnect\" href=\"https:\/\/fonts.googleapis.com\">\n<link href=\"https:\/\/fonts.googleapis.com\/css2?family=Inter:wght@400;500;600;700;800&amp;display=swap\" rel=\"stylesheet\">\n<style>\n  :root{\n    --ink:#161B33;\n    --ink-deep:#0B0F1F;\n    --accent:#2F8FE8;\n    --accent-deep:#1C6FC4;\n  }\n  *{box-sizing:border-box;}\n  body{margin:0;font-family:'Inter',system-ui,-apple-system,sans-serif;background:#eef0f4;color:var(--ink);}\n\n  \/* ================= SERVICES: cog menu -> full-screen reel + content detail ================= *\/\n  .services-section{position:relative;background:var(--ink-deep);padding:130px 24px 150px;overflow:hidden;}\n  .services-section::before{\n    content:'';position:absolute;inset:0;\n    background:radial-gradient(ellipse 70% 50% at 50% 15%, rgba(47,143,232,0.16), transparent 70%);\n    pointer-events:none;\n  }\n  .services-intro{position:relative;max-width:620px;margin:0 auto 76px;text-align:center;}\n  .services__eyebrow{display:flex;align-items:center;justify-content:center;gap:14px;margin-bottom:16px;}\n  .services__eyebrow .rule{width:40px;height:3px;background:var(--accent);border-radius:2px;}\n  .services__eyebrow span{font-size:0.78rem;font-weight:700;letter-spacing:0.12em;text-transform:uppercase;color:#8fc4f7;}\n  .services-heading{color:#fff;font-size:2rem;font-weight:800;margin:0 0 14px;letter-spacing:-0.01em;}\n  .services-sub{color:rgba(255,255,255,0.6);font-size:0.98rem;line-height:1.6;margin:0;}\n\n  \/* ---- cog wheel ---- *\/\n  .cog-scene{perspective:1400px;width:700px;margin:0 auto;}\n  .cog-wrap{\n    position:relative;\n    width:700px;height:700px;\n    --radius-inner:150px;\n    --radius-outer:275px;\n    display:flex;align-items:center;justify-content:center;\n    transform-style:preserve-3d;\n    transition:transform 0.25s ease-out;\n  }\n\n  .cog-connectors{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:1;overflow:visible;}\n  .cog-connectors line{\n    stroke:var(--accent);\n    stroke-width:1.5;\n    stroke-linecap:round;\n    opacity:0;\n    filter:drop-shadow(0 0 4px rgba(47,143,232,0.55));\n    transition:opacity 0.4s ease, stroke-dashoffset 0.7s cubic-bezier(.22,1,.36,1);\n  }\n  .cog-connectors line.is-visible{opacity:0.6;}\n\n  .cog-ring-decor{position:absolute;inset:0;}\n  .cog-ring-decor svg{position:absolute;inset:0;width:100%;height:100%;}\n  .cog-ring-decor .ring-outer{animation:cog-spin 46s linear infinite;}\n  .cog-ring-decor .ring-mid{animation:cog-spin-rev 68s linear infinite;}\n  .cog-ring-decor .ring-teeth{animation:cog-spin 90s linear infinite;}\n  @keyframes cog-spin{ to{ transform:rotate(360deg); } }\n  @keyframes cog-spin-rev{ to{ transform:rotate(-360deg); } }\n\n  .cog-hub{\n    position:relative;z-index:2;\n    width:150px;height:150px;border-radius:50%;\n    background:rgba(255,255,255,0.04);\n    border:1px solid rgba(255,255,255,0.14);\n    backdrop-filter:blur(6px);\n    display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;\n    color:#fff;\n    cursor:default;\n    box-shadow:0 0 0 1px rgba(47,143,232,0.15), 0 0 46px rgba(47,143,232,0.18);\n    animation:hub-pulse 4.5s ease-in-out infinite;\n    transition:box-shadow 0.3s ease;\n    padding:10px;\n  }\n  @keyframes hub-pulse{\n    0%,100%{ box-shadow:0 0 0 1px rgba(47,143,232,0.15), 0 0 30px rgba(47,143,232,0.14); }\n    50%{ box-shadow:0 0 0 1px rgba(47,143,232,0.35), 0 0 56px rgba(47,143,232,0.3); }\n  }\n  .cog-hub strong{font-size:0.98rem;font-weight:800;letter-spacing:-0.01em;line-height:1.25;}\n  .cog-hub span{font-size:0.62rem;color:#8fc4f7;letter-spacing:0.08em;text-transform:uppercase;margin-top:6px;line-height:1.4;}\n  .cog-wrap.has-active .cog-hub{cursor:pointer;}\n  .cog-wrap.has-active .cog-hub:hover{box-shadow:0 0 0 1px rgba(47,143,232,0.45), 0 0 56px rgba(47,143,232,0.32);}\n\n  .cog-node{\n    position:absolute;top:50%;left:50%;\n    width:84px;height:84px;border-radius:50%;\n    background:rgba(255,255,255,0.05);\n    border:1px solid rgba(255,255,255,0.14);\n    backdrop-filter:blur(6px);\n    display:flex;flex-direction:column;align-items:center;justify-content:center;gap:7px;\n    color:#cfe0f7;\n    cursor:pointer;\n    font-family:inherit;\n    padding:8px;\n    opacity:0;\n    transform:translate(-50%,-50%) translate(var(--tx), var(--ty)) scale(0.3);\n    transition:transform 0.5s cubic-bezier(.34,1.56,.64,1), background 0.3s ease, border-color 0.3s ease, box-shadow 0.3s ease, color 0.3s ease, opacity 0.5s ease;\n  }\n  .cog-node.is-visible{opacity:1;transform:translate(-50%,-50%) translate(var(--tx), var(--ty)) scale(1);}\n  .cog-node svg{width:26px;height:26px;stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;transition:transform 0.4s cubic-bezier(.34,1.56,.64,1);}\n  .cog-node__label{font-size:0.6rem;font-weight:700;letter-spacing:0.02em;text-align:center;line-height:1.25;max-width:76px;}\n  .cog-node:hover, .cog-node:focus-visible{\n    background:rgba(47,143,232,0.16);\n    border-color:var(--accent);\n    color:#fff;\n    box-shadow:0 0 0 1px var(--accent), 0 14px 34px rgba(47,143,232,0.4);\n    transform:translate(-50%,-50%) translate(var(--tx), var(--ty)) scale(1.14);\n  }\n  .cog-node:hover svg{transform:rotate(-12deg) scale(1.08);}\n  .cog-node:focus-visible{outline:none;}\n\n  \/* category (inner ring) active \/ dimmed states *\/\n  .cog-node--inner.is-active{\n    background:rgba(47,143,232,0.2);\n    border-color:var(--accent);\n    color:#fff;\n    box-shadow:0 0 0 1px var(--accent), 0 16px 38px rgba(47,143,232,0.42);\n  }\n  .cog-wrap.has-active .cog-node--inner:not(.is-active){opacity:0.4;}\n\n  .cog-node--outer{width:72px;height:72px;}\n  .cog-node--outer svg{width:22px;height:22px;}\n  .cog-node--outer .cog-node__label{font-size:0.54rem;max-width:64px;}\n\n  @media (max-width:900px){\n    .cog-scene, .cog-wrap{width:430px;height:430px;}\n    .cog-wrap{--radius-inner:95px;--radius-outer:178px;}\n    .cog-node{width:60px;height:60px;}\n    .cog-node svg{width:18px;height:18px;}\n    .cog-node__label{font-size:0.46rem;max-width:52px;}\n    .cog-node--outer{width:52px;height:52px;}\n    .cog-node--outer svg{width:15px;height:15px;}\n    .cog-node--outer .cog-node__label{font-size:0.4rem;max-width:44px;}\n    .cog-hub{width:100px;height:100px;}\n    .cog-hub strong{font-size:0.72rem;}\n    .cog-hub span{font-size:0.52rem;}\n  }\n\n  @media (prefers-reduced-motion:reduce){\n    .cog-ring-decor *, .cog-hub{animation:none !important;}\n    .cog-connectors line{transition:none !important;}\n  }\n\n  \/* ---- full-screen expanded service view ---- *\/\n  .service-overlay{\n    position:fixed;inset:0;z-index:200;\n    background:var(--ink-deep);\n    opacity:0;pointer-events:none;\n    transition:opacity 0.5s ease;\n    overflow:hidden;\n  }\n  .service-overlay.is-open{opacity:1;pointer-events:auto;}\n\n  .service-ambient{position:absolute;inset:0;}\n  .service-ambient__layer{\n    position:absolute;inset:-6%;\n    background-size:cover;background-position:center;\n    filter:blur(30px) saturate(1.2);\n    transform:scale(1.1);\n    opacity:0;\n    transition:opacity 1s ease;\n    animation:ambient-drift 22s ease-in-out infinite alternate;\n  }\n  .service-ambient__layer.is-active{opacity:0.85;}\n  .service-ambient__scrim{position:absolute;inset:0;background:linear-gradient(115deg, rgba(6,9,20,0.82) 0%, rgba(6,9,20,0.6) 42%, rgba(6,9,20,0.42) 100%);}\n  @keyframes ambient-drift{\n    0%{ transform:scale(1.1) translate(0,0); }\n    100%{ transform:scale(1.18) translate(-1.5%, 1%); }\n  }\n\n  .service-back{\n    position:absolute;top:28px;left:28px;z-index:6;\n    display:inline-flex;align-items:center;gap:8px;\n    background:rgba(255,255,255,0.08);border:1px solid rgba(255,255,255,0.22);\n    color:#fff;font-family:inherit;font-weight:700;font-size:0.78rem;letter-spacing:0.04em;text-transform:uppercase;\n    padding:11px 20px 11px 15px;border-radius:999px;cursor:pointer;backdrop-filter:blur(8px);\n    transition:background 0.25s ease, transform 0.25s ease;\n  }\n  .service-back:hover{background:rgba(47,143,232,0.28);transform:translateX(-3px);}\n  .service-back svg{width:16px;height:16px;stroke:#fff;stroke-width:2;}\n\n  .service-progress{\n    position:absolute;top:34px;right:32px;z-index:6;\n    color:rgba(255,255,255,0.55);font-size:0.78rem;font-weight:700;letter-spacing:0.05em;\n    text-align:right;\n  }\n  .service-progress b{color:#fff;}\n  .service-progress__category{\n    display:block;font-size:0.62rem;color:#8fc4f7;letter-spacing:0.08em;text-transform:uppercase;margin-top:3px;font-weight:700;\n  }\n\n  .service-stage{\n    position:relative;z-index:2;height:100%;\n    display:flex;align-items:stretch;justify-content:center;\n    gap:56px;\n    padding:112px 56px 48px;\n  }\n\n  \/* ---- left column: the word reel (menu) ---- *\/\n  .service-menu-col{\n    flex:0 0 320px;\n    display:flex;align-items:center;justify-content:flex-end;\n    -webkit-mask-image:linear-gradient(to bottom, transparent 0%, #000 18%, #000 82%, transparent 100%);\n    mask-image:linear-gradient(to bottom, transparent 0%, #000 18%, #000 82%, transparent 100%);\n  }\n  .service-reel{\n    position:relative;\n    width:100%;\n    height:100%;\n    perspective:900px;\n    display:flex;align-items:center;justify-content:flex-end;\n  }\n  .reel-item{\n    position:absolute;top:50%;right:0;\n    white-space:nowrap;\n    font-weight:800;\n    letter-spacing:-0.015em;\n    color:rgba(255,255,255,0.34);\n    cursor:pointer;\n    display:flex;align-items:center;gap:12px;\n    transition:transform 0.55s cubic-bezier(.34,1.1,.4,1), opacity 0.55s ease, filter 0.55s ease, color 0.4s ease;\n  }\n  .reel-item__icon{\n    width:22px;height:22px;flex:0 0 auto;\n    stroke:currentColor;fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;\n    transition:stroke 0.4s ease;\n  }\n  .reel-item__arrow{\n    color:var(--accent);\n    font-size:1.1em;\n    opacity:0;\n    transform:translateX(-8px);\n    transition:opacity 0.35s ease, transform 0.35s ease;\n  }\n  .reel-item.is-focus{color:#fff;animation:reel-focus-float 3.2s ease-in-out infinite;}\n  .reel-item.is-focus .reel-item__arrow{opacity:1;transform:translateX(0);}\n  @keyframes reel-focus-float{\n    0%,100%{ margin-top:0; }\n    50%{ margin-top:-4px; }\n  }\n\n  \/* ---- right column: content card ---- *\/\n  .service-content-col{\n    flex:1 1 560px;max-width:600px;\n    display:flex;flex-direction:column;justify-content:center;\n    overflow:hidden;\n    padding:12px 6px;\n  }\n  .service-card{\n    --fit-scale:1;\n    width:100%;\n    background:rgba(255,255,255,0.07);\n    border:1px solid rgba(255,255,255,0.18);\n    border-radius:26px;\n    backdrop-filter:blur(26px) saturate(160%);\n    -webkit-backdrop-filter:blur(26px) saturate(160%);\n    box-shadow:0 30px 90px -30px rgba(0,0,0,0.7), inset 0 1px 0 rgba(255,255,255,0.2);\n    overflow-y:auto;overflow-x:hidden;\n    scrollbar-width:thin;scrollbar-color:rgba(47,143,232,0.5) transparent;\n    opacity:0;transform:translateX(26px);\n    transition:opacity 0.5s ease, transform 0.5s cubic-bezier(.22,1,.36,1);\n  }\n  .service-card::-webkit-scrollbar{width:6px;}\n  .service-card::-webkit-scrollbar-track{background:transparent;}\n  .service-card::-webkit-scrollbar-thumb{background:rgba(47,143,232,0.5);border-radius:3px;}\n  .service-card.is-visible{opacity:1;transform:translateX(0);}\n\n  .service-card__image-wrap{position:relative;width:100%;height:calc(200px * var(--fit-scale));overflow:hidden;}\n  .service-card.is-image-hidden .service-card__image-wrap{height:0;}\n  .service-card__image{width:100%;height:100%;object-fit:cover;display:block;transform:scale(1.02);}\n  .service-card__image-wrap::after{\n    content:'';position:absolute;inset:0;\n    background:linear-gradient(180deg, rgba(11,15,31,0) 40%, rgba(11,15,31,0.7) 100%);\n  }\n  .service-card__icon-badge{\n    position:relative;z-index:2;\n    margin:calc(-38px * var(--fit-scale)) 0 0 28px;\n    width:calc(58px * var(--fit-scale));height:calc(58px * var(--fit-scale));border-radius:15px;\n    background:rgba(11,15,31,0.85);\n    border:1px solid rgba(47,143,232,0.5);\n    display:flex;align-items:center;justify-content:center;\n    box-shadow:0 10px 26px rgba(0,0,0,0.45);\n  }\n  .service-card.is-image-hidden .service-card__icon-badge{margin-top:24px;}\n  .service-card__icon-badge svg{width:calc(28px * var(--fit-scale));height:calc(28px * var(--fit-scale));stroke:var(--accent);fill:none;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round;}\n\n  .service-card__body{padding:calc(22px * var(--fit-scale)) calc(34px * var(--fit-scale)) calc(34px * var(--fit-scale));color:#fff;}\n  .service-card__title{font-size:calc(1.55rem * var(--fit-scale));font-weight:800;margin:0 0 calc(14px * var(--fit-scale));letter-spacing:-0.01em;}\n  .service-card__desc p{font-size:calc(0.92rem * var(--fit-scale));line-height:1.65;color:rgba(255,255,255,0.8);margin:0 0 calc(13px * var(--fit-scale));}\n  .service-card__desc p:last-child{margin-bottom:0;}\n\n  .service-card__cta{\n    display:inline-flex;align-items:center;gap:8px;margin-top:calc(22px * var(--fit-scale));\n    background:var(--accent);color:#fff;text-decoration:none;\n    font-weight:700;font-size:0.8rem;letter-spacing:0.04em;text-transform:uppercase;\n    padding:13px 26px;border-radius:999px;\n    transition:background 0.3s ease, transform 0.3s ease;\n  }\n  .service-card__cta:hover{background:var(--accent-deep);transform:translateY(-2px);}\n\n  .service-nav-hint{\n    position:absolute;bottom:20px;left:50%;transform:translateX(-50%);z-index:6;\n    display:flex;flex-direction:column;align-items:center;gap:3px;\n    color:rgba(255,255,255,0.4);font-size:0.62rem;letter-spacing:0.1em;text-transform:uppercase;\n    pointer-events:none;\n  }\n  .service-nav-hint svg{width:14px;height:14px;stroke:rgba(255,255,255,0.4);animation:hint-bounce 1.8s ease-in-out infinite;}\n  @keyframes hint-bounce{ 0%,100%{transform:translateY(0);} 50%{transform:translateY(4px);} }\n\n  @media (max-width:900px){\n    .service-stage{flex-direction:column;padding:96px 22px 30px;gap:18px;align-items:center;}\n    .service-menu-col{\n      flex:0 0 150px;width:100%;justify-content:center;\n      -webkit-mask-image:linear-gradient(to right, transparent 0%, #000 12%, #000 88%, transparent 100%);\n      mask-image:linear-gradient(to right, transparent 0%, #000 12%, #000 88%, transparent 100%);\n    }\n    .service-reel{justify-content:center;}\n    .reel-item{right:auto;left:50%;transform-origin:center;}\n    .service-content-col{max-width:100%;}\n    .service-back{top:20px;left:20px;}\n    .service-progress{top:26px;right:20px;}\n  }\n\n  @media (prefers-reduced-motion:reduce){\n    .service-overlay, .service-ambient__layer, .service-card, .reel-item, .service-nav-hint svg, .cog-hub{transition:none !important;animation:none !important;}\n  }\n<\/style>\n\n\n\n<section class=\"services-section\" id=\"servicesSection\">\n  <div class=\"services-intro\">\n    <div class=\"services__eyebrow\"><div class=\"rule\"><\/div><span>Our Services<\/span><\/div>\n    <h2 class=\"services-heading\">IT solutions built around your business<\/h2>\n    <p class=\"services-sub\">Choose an area below, then explore how we design, secure, and scale the systems your business runs on.<\/p>\n  <\/div>\n\n  <div class=\"cog-scene\">\n    <div class=\"cog-wrap\" id=\"cogWrap\">\n      <div class=\"cog-ring-decor\">\n        <svg class=\"ring-outer\" viewBox=\"0 0 700 700\" aria-hidden=\"true\">\n          <circle cx=\"350\" cy=\"350\" r=\"340\" fill=\"none\" stroke=\"rgba(47,143,232,0.4)\" stroke-width=\"2\" stroke-dasharray=\"1 13\" stroke-linecap=\"round\"><\/circle>\n        <\/svg>\n        <svg class=\"ring-teeth\" viewBox=\"0 0 700 700\" aria-hidden=\"true\">\n          <circle cx=\"350\" cy=\"350\" r=\"313\" fill=\"none\" stroke=\"rgba(255,255,255,0.14)\" stroke-width=\"6\" stroke-dasharray=\"4 20\" stroke-linecap=\"butt\"><\/circle>\n          <circle cx=\"350\" cy=\"350\" r=\"188\" fill=\"none\" stroke=\"rgba(255,255,255,0.1)\" stroke-width=\"4\" stroke-dasharray=\"3 15\" stroke-linecap=\"butt\"><\/circle>\n        <\/svg>\n        <svg class=\"ring-mid\" viewBox=\"0 0 700 700\" aria-hidden=\"true\">\n          <circle cx=\"350\" cy=\"350\" r=\"290\" fill=\"none\" stroke=\"rgba(255,255,255,0.07)\" stroke-width=\"1\"><\/circle>\n          <circle cx=\"350\" cy=\"350\" r=\"170\" fill=\"none\" stroke=\"rgba(255,255,255,0.07)\" stroke-width=\"1\"><\/circle>\n        <\/svg>\n      <\/div>\n      <svg class=\"cog-connectors\" id=\"cogConnectors\" aria-hidden=\"true\"><\/svg>\n      <div class=\"cog-hub\" id=\"cogHub\"><strong id=\"cogHubStrong\">Services<\/strong><span id=\"cogHubSpan\">Tap an area to explore<\/span><\/div>\n      <div id=\"cogNodes\"><\/div>\n    <\/div>\n  <\/div>\n<\/section>\n\n<div class=\"service-overlay\" id=\"serviceOverlay\" aria-hidden=\"true\">\n  <div class=\"service-ambient\" id=\"serviceAmbient\"><\/div>\n  <button class=\"service-back\" id=\"serviceBack\" aria-label=\"Back to services\">\n    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"15 18 9 12 15 6\"><\/polyline><\/svg>\n    Back\n  <\/button>\n  <div class=\"service-progress\" id=\"serviceProgress\"><\/div>\n\n  <div class=\"service-stage\" id=\"serviceStage\">\n    <div class=\"service-menu-col\">\n      <div class=\"service-reel\" id=\"serviceReel\"><\/div>\n    <\/div>\n\n    <div class=\"service-content-col\" id=\"serviceContentCol\">\n      <div class=\"service-card\" id=\"serviceCard\">\n        <div class=\"service-card__image-wrap\">\n          <img decoding=\"async\" class=\"service-card__image\" id=\"serviceCardImage\" src=\"\" alt=\"\">\n        <\/div>\n        <div class=\"service-card__icon-badge\" id=\"serviceCardIcon\"><\/div>\n        <div class=\"service-card__body\">\n          <h3 class=\"service-card__title\" id=\"serviceCardTitle\"><\/h3>\n          <div class=\"service-card__desc\" id=\"serviceCardDesc\"><\/div>\n          <a class=\"service-card__cta\" href=\"https:\/\/monichron.co.za\/index.php\/contact-2\/\" target=\"_blank\" rel=\"noopener noreferrer\">Enquire About This Service \u2192<\/a>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"service-nav-hint\">\n    <svg viewBox=\"0 0 24 24\" fill=\"none\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"6 9 12 15 18 9\"><\/polyline><\/svg>\n    Scroll menu to browse\n  <\/div>\n<\/div>\n\n<script>\n(function(){\n  var ICONS = {\n    database:'<svg viewBox=\"0 0 24 24\"><ellipse cx=\"12\" cy=\"5\" rx=\"8\" ry=\"3\"\/><path d=\"M4 5v6c0 1.66 3.58 3 8 3s8-1.34 8-3V5\"\/><path d=\"M4 11v6c0 1.66 3.58 3 8 3s8-1.34 8-3v-6\"\/><\/svg>',\n    shield:'<svg viewBox=\"0 0 24 24\"><path d=\"M12 3l7 3v5c0 5-3 8.5-7 10-4-1.5-7-5-7-10V6l7-3z\"\/><path d=\"M9 12l2 2 4-4\"\/><\/svg>',\n    grid:'<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"3\" width=\"7\" height=\"7\" rx=\"1.5\"\/><rect x=\"14\" y=\"3\" width=\"7\" height=\"7\" rx=\"1.5\"\/><rect x=\"3\" y=\"14\" width=\"7\" height=\"7\" rx=\"1.5\"\/><rect x=\"14\" y=\"14\" width=\"7\" height=\"7\" rx=\"1.5\"\/><\/svg>',\n    cloud:'<svg viewBox=\"0 0 24 24\"><path d=\"M7 18h10a4 4 0 0 0 .6-7.96A6 6 0 0 0 6.2 9.1 4 4 0 0 0 7 18z\"\/><\/svg>',\n    code:'<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"\/><line x1=\"3\" y1=\"9\" x2=\"21\" y2=\"9\"\/><path d=\"M8 14l-2 2 2 2\"\/><path d=\"M13 14l2 2-2 2\"\/><\/svg>',\n    chart:'<svg viewBox=\"0 0 24 24\"><line x1=\"4\" y1=\"20\" x2=\"4\" y2=\"12\"\/><line x1=\"10\" y1=\"20\" x2=\"10\" y2=\"7\"\/><line x1=\"16\" y1=\"20\" x2=\"16\" y2=\"14\"\/><line x1=\"20\" y1=\"20\" x2=\"20\" y2=\"4\"\/><\/svg>',\n    layers:'<svg viewBox=\"0 0 24 24\"><path d=\"M12 2l9 5-9 5-9-5 9-5z\"\/><path d=\"M3 12l9 5 9-5\"\/><path d=\"M3 17l9 5 9-5\"\/><\/svg>',\n    cap:'<svg viewBox=\"0 0 24 24\"><path d=\"M22 10L12 5 2 10l10 5 10-5z\"\/><path d=\"M6 12v5c0 1.5 2.5 3 6 3s6-1.5 6-3v-5\"\/><\/svg>',\n    flow:'<svg viewBox=\"0 0 24 24\"><circle cx=\"6\" cy=\"6\" r=\"2.5\"\/><circle cx=\"6\" cy=\"18\" r=\"2.5\"\/><circle cx=\"18\" cy=\"12\" r=\"2.5\"\/><path d=\"M6 8.5v7\"\/><path d=\"M8.2 7l7.6 3.8\"\/><path d=\"M8.2 17l7.6-3.8\"\/><\/svg>',\n    server:'<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"6\" rx=\"1.5\"\/><rect x=\"3\" y=\"14\" width=\"18\" height=\"6\" rx=\"1.5\"\/><line x1=\"7\" y1=\"7\" x2=\"7.01\" y2=\"7\"\/><line x1=\"7\" y1=\"17\" x2=\"7.01\" y2=\"17\"\/><\/svg>',\n    monitor:'<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"4\" width=\"18\" height=\"12\" rx=\"1.5\"\/><line x1=\"8\" y1=\"20\" x2=\"16\" y2=\"20\"\/><line x1=\"12\" y1=\"16\" x2=\"12\" y2=\"20\"\/><\/svg>',\n    network:'<svg viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"5\" r=\"2\"\/><circle cx=\"5\" cy=\"19\" r=\"2\"\/><circle cx=\"19\" cy=\"19\" r=\"2\"\/><path d=\"M12 7v4\"\/><path d=\"M12 11l-5.5 6\"\/><path d=\"M12 11l5.5 6\"\/><\/svg>',\n    dbadmin:'<svg viewBox=\"0 0 24 24\"><ellipse cx=\"9\" cy=\"5\" rx=\"6\" ry=\"2.3\"\/><path d=\"M3 5v12c0 1.3 2.7 2.3 6 2.3\"\/><path d=\"M15 5v3\"\/><circle cx=\"18\" cy=\"15\" r=\"3.2\"\/><path d=\"M18 11.8v-1M18 19.2v-1M21.2 13.4l-.9.5M15.7 16.1l-.9.5M21.2 16.6l-.9-.5M15.7 13.9l-.9-.5\"\/><\/svg>',\n    share:'<svg viewBox=\"0 0 24 24\"><circle cx=\"6\" cy=\"12\" r=\"2.5\"\/><circle cx=\"18\" cy=\"6\" r=\"2.5\"\/><circle cx=\"18\" cy=\"18\" r=\"2.5\"\/><path d=\"M8.2 10.8l7.6-3.6\"\/><path d=\"M8.2 13.2l7.6 3.6\"\/><\/svg>',\n    kanban:'<svg viewBox=\"0 0 24 24\"><rect x=\"3\" y=\"4\" width=\"7\" height=\"16\" rx=\"1.2\"\/><rect x=\"14\" y=\"4\" width=\"7\" height=\"9\" rx=\"1.2\"\/><line x1=\"5.5\" y1=\"8\" x2=\"7.5\" y2=\"8\"\/><line x1=\"16.5\" y1=\"8\" x2=\"18.5\" y2=\"8\"\/><\/svg>',\n    cloudcheck:'<svg viewBox=\"0 0 24 24\"><path d=\"M7 18h9a4 4 0 0 0 .6-7.96A6 6 0 0 0 6.2 9.1 4 4 0 0 0 7 18z\"\/><path d=\"M9.5 13.5l2 2 4-4\"\/><\/svg>'\n  };\n\n  var SERVICES = [\n    {\n      name:\"Database Development and Implementation\",\n      slug:\"svc-database\",\n      shortLabel:\"Database Dev\",\n      icon:\"database\",\n      photo:\"https:\/\/images.pexels.com\/photos\/17323801\/pexels-photo-17323801.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Database Development and Implementation service is dedicated to creating customized and scalable database solutions that cater to the specific data management needs of businesses. We start by thoroughly understanding the unique data requirements of our clients and then proceed to design and implement robust database architectures that ensure seamless data storage, retrieval, and management. With a focus on data security and accessibility, we optimize the performance of the databases, enabling businesses to handle their data efficiently and make informed decisions that drive growth and productivity.\",\n        \"Furthermore, our ongoing support and maintenance services ensure the seamless performance and optimization of the databases. We provide regular updates, data backups, and system enhancements, coupled with proactive monitoring to address any potential issues swiftly. Our holistic approach to database development and implementation aims to empower businesses with reliable and secure data management solutions that not only meet their current needs but also adapt and scale with their future growth and evolving data requirements.\"\n      ]\n    },\n    {\n      name:\"Data Security and Privacy Solutions\",\n      slug:\"svc-security\",\n      shortLabel:\"Data Security\",\n      icon:\"shield\",\n      photo:\"https:\/\/images.pexels.com\/photos\/11391947\/pexels-photo-11391947.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"At Monichron, our Data Security and Privacy Solutions are meticulously designed to provide comprehensive protection for sensitive data assets. Leveraging advanced encryption techniques and proactive security measures, we create tailored strategies to mitigate risks, ensure compliance with data privacy regulations, and safeguard data integrity. Our solutions empower businesses to build and maintain trust with their customers and stakeholders, fostering a secure environment that prioritizes data privacy and confidentiality.\",\n        \"Additionally, we conduct regular security audits and assessments to identify potential vulnerabilities and address them proactively, ensuring that our clients' data remains secure at all times. Our team of experts remains vigilant in monitoring data access and usage, providing comprehensive training and guidance to employees to ensure data security protocols are followed meticulously. With our unwavering commitment to data security and privacy, businesses can operate with confidence, knowing that their sensitive information is well-protected and compliant with industry regulations and standards.\"\n      ]\n    },\n    {\n      name:\"ERP Implementation and Support\",\n      slug:\"svc-erp\",\n      shortLabel:\"ERP\",\n      icon:\"grid\",\n      photo:\"https:\/\/images.pexels.com\/photos\/5466238\/pexels-photo-5466238.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our ERP Implementation and Support service is focused on streamlining business processes and enhancing resource management through the seamless integration of enterprise resource planning systems. Starting with a detailed analysis of the existing infrastructure and operational requirements, we develop a customized ERP implementation strategy that aligns with our clients' specific business objectives. Our comprehensive support services ensure a smooth transition and continued operational efficiency, allowing businesses to optimize their processes and drive growth with confidence.\",\n        \"Our support services extend beyond the implementation phase, encompassing comprehensive training programs and user workshops to equip employees with the necessary skills to effectively utilize the ERP system. We offer round-the-clock assistance and troubleshooting support to address any issues promptly, ensuring uninterrupted business operations and maximum system uptime. With our ERP implementation and support, businesses can streamline their processes, improve cross-departmental collaboration, and drive overall productivity, positioning themselves for sustained success and growth in their respective industries.\"\n      ]\n    },\n    {\n      name:\"CRM Cloud Solutions\",\n      slug:\"svc-crm\",\n      shortLabel:\"CRM Cloud\",\n      icon:\"cloud\",\n      photo:\"https:\/\/images.pexels.com\/photos\/7693156\/pexels-photo-7693156.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"With our CRM Cloud Solutions, we craft agile and scalable customer relationship management systems that enhance customer engagement and streamline interactions. Our tailored cloud-based solutions empower businesses to build strong and lasting relationships with their customers by providing a seamless and personalized experience. By leveraging data-driven insights, our CRM solutions enable businesses to better understand customer behavior and preferences, ultimately driving business growth and fostering customer loyalty.\",\n        \"Moreover, our CRM solutions enable businesses to track customer interactions, manage sales pipelines, and analyze customer data to gain valuable insights into customer behavior and preferences. Through personalized marketing and targeted communication strategies, we help businesses enhance customer retention and satisfaction, fostering long-term relationships and brand loyalty. Our CRM cloud solutions are designed to adapt and scale with businesses, allowing them to stay agile and responsive to changing market dynamics, ultimately driving sustainable business growth and profitability.\"\n      ]\n    },\n    {\n      name:\"Dynamic App and Web Design\",\n      slug:\"svc-web\",\n      shortLabel:\"App & Web\",\n      icon:\"code\",\n      photo:\"https:\/\/images.pexels.com\/photos\/3888151\/pexels-photo-3888151.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Dynamic App and Web Design service is dedicated to creating engaging and user-friendly digital experiences that cater to the unique needs of businesses. Through innovative design strategies and advanced development techniques, we craft dynamic applications and websites that effectively communicate the brand's message and offerings. By focusing on user experience and interface design, we ensure that our solutions are intuitive, visually appealing, and optimized for performance, providing businesses with a competitive edge in the digital landscape.\",\n        \"Additionally, we conduct thorough usability testing and performance optimization to ensure that our applications and websites deliver a seamless and responsive user experience across various devices and platforms. We continuously monitor and analyze user feedback to make iterative improvements and enhancements, keeping the digital presence of businesses relevant and engaging. With our dynamic app and web design services, businesses can effectively connect with their target audience, drive user engagement, and establish a strong online presence that sets them apart from the competition.\"\n      ]\n    },\n    {\n      name:\"Data Analytics\",\n      slug:\"svc-analytics\",\n      shortLabel:\"Analytics\",\n      icon:\"chart\",\n      photo:\"https:\/\/images.pexels.com\/photos\/7947742\/pexels-photo-7947742.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Unlock the power of data with our comprehensive Data Analytics service, designed to provide businesses with actionable insights and strategic intelligence. Leveraging advanced analytics tools and methodologies, we analyze complex data sets to extract valuable business insights, enabling businesses to make informed decisions and drive growth. Our data analytics solutions help businesses uncover patterns, trends, and opportunities within their data, empowering them to stay ahead in today's dynamic market landscape and achieve their business objectives with confidence.\",\n        \"Our data analytics services encompass regular performance evaluations and in-depth analysis to identify emerging trends and opportunities for business growth. We provide actionable insights and data-driven recommendations that help businesses refine their strategies and make informed decisions that drive competitive advantage and market leadership. With our advanced data analytics capabilities, businesses can unlock the full potential of their data assets, optimize operational processes, and capitalize on new business opportunities, positioning themselves for sustained success and innovation in an increasingly data-driven business landscape.\"\n      ]\n    },\n    {\n      name:\"Reporting, Data Warehousing & BI\",\n      slug:\"svc-bi\",\n      shortLabel:\"Reporting & BI\",\n      icon:\"layers\",\n      photo:\"https:\/\/images.pexels.com\/photos\/6424590\/pexels-photo-6424590.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Reporting, Data Warehousing and Business Intelligence service consolidates data scattered across your operational systems into a single, reliable source of truth. We design data warehouses that pull information from ERP, CRM, and financial systems into structured, query-ready repositories, then build the reporting layer on top, from scheduled operational reports to interactive dashboards, so decision-makers see accurate, up-to-date figures without manually collating spreadsheets.\",\n        \"Beyond the initial build, we focus on making BI genuinely useful day to day: sensible data models, clear naming conventions, and dashboards built around the questions your business actually asks. We provide training so internal teams can extend reports themselves, along with ongoing support to keep data pipelines running as source systems change, ensuring your reporting stays trustworthy as the business grows.\"\n      ]\n    },\n    {\n      name:\"Business Systems Training\",\n      slug:\"svc-training\",\n      shortLabel:\"Systems Training\",\n      icon:\"cap\",\n      photo:\"https:\/\/images.pexels.com\/photos\/18999469\/pexels-photo-18999469.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Training service equips your staff to get real value from the systems they use every day, covering Excel, SYSPRO, Microsoft Dynamics 365, Oracle, Sage, Pastel, and SAP. Sessions are tailored to how your team actually works, from core data-entry and reporting workflows for new users to advanced techniques for power users, so training translates directly into fewer errors and faster, more confident use of the software.\",\n        \"We combine structured, role-based curricula with hands-on practice in your own environment, and follow up with reference material staff can return to after the session. Whether you're onboarding new employees, rolling out a new module, or simply raising the general skill level across a department, our training is designed to reduce reliance on ad hoc support and help your team become self-sufficient.\"\n      ]\n    },\n    {\n      name:\"Business Analysis and Process Re-engineering\",\n      slug:\"svc-businessanalysis\",\n      shortLabel:\"Business Analysis\",\n      icon:\"flow\",\n      photo:\"https:\/\/images.pexels.com\/photos\/17724732\/pexels-photo-17724732.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Business Analysis and Process Re-engineering service starts with understanding how work actually happens in your business, not just how it's documented. We map current processes, identify bottlenecks, duplicated effort, and manual workarounds, and translate those findings into clear requirements that guide system changes, integrations, or new tooling with a defined business case behind them.\",\n        \"Where processes themselves need to change, we redesign workflows around the outcomes you're trying to achieve, balancing efficiency gains against the practical realities of your team and industry. We work alongside stakeholders throughout implementation to ensure new processes are adopted properly, not just documented, and measure results against the original business case so the value of the change is clear.\"\n      ]\n    },\n    {\n      name:\"Server Support\",\n      slug:\"svc-serversupport\",\n      shortLabel:\"Server Support\",\n      icon:\"server\",\n      photo:\"https:\/\/images.pexels.com\/photos\/5480781\/pexels-photo-5480781.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Server Support service keeps the infrastructure your business depends on running reliably, covering physical and virtual servers, patching, backups, and performance monitoring. We proactively identify issues, such as failing disks, resource bottlenecks, and ageing hardware, before they become downtime, and respond quickly when incidents do occur to minimise disruption to your operations.\",\n        \"We also handle capacity planning and lifecycle management, advising on when to upgrade, virtualise, or migrate workloads to keep infrastructure aligned with business needs and budget. With clear documentation and defined response times, our server support gives businesses the confidence that their core systems are properly maintained and monitored around the clock.\"\n      ]\n    },\n    {\n      name:\"Desktop Support\",\n      slug:\"svc-desktopsupport\",\n      shortLabel:\"Desktop Support\",\n      icon:\"monitor\",\n      photo:\"https:\/\/images.pexels.com\/photos\/37605911\/pexels-photo-37605911.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Desktop Support service provides responsive, day-to-day IT support for your staff's workstations and devices, from hardware and software troubleshooting to account access, printer issues, and application errors. We aim to resolve problems quickly so employees can get back to work with minimal disruption, whether support is needed on-site or remotely.\",\n        \"Beyond reactive fixes, we standardise device setup and configuration to reduce recurring issues, and keep systems patched and secure without interrupting daily work. Our desktop support is built around clear ticketing and communication, so staff always know the status of their request and businesses have visibility into recurring problem areas worth addressing at the root.\"\n      ]\n    },\n    {\n      name:\"Network Security\",\n      slug:\"svc-netsecurity\",\n      shortLabel:\"Network Security\",\n      icon:\"network\",\n      photo:\"https:\/\/images.pexels.com\/photos\/5380618\/pexels-photo-5380618.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Network Security service protects the infrastructure that connects your business, including firewalls, VPNs, wireless networks, and remote access, against unauthorised access and evolving threats. We design and configure network architecture with security as a first principle, segmenting traffic, enforcing access controls, and closing off unnecessary exposure without compromising day-to-day usability.\",\n        \"We complement this with ongoing monitoring, patching, and vulnerability assessments to catch weaknesses before they're exploited, along with clear incident response procedures should something go wrong. Our goal is a network that's resilient by design, giving businesses confidence that both their internal systems and remote connections remain protected as the threat landscape changes.\"\n      ]\n    },\n    {\n      name:\"Database Administration\",\n      slug:\"svc-dba\",\n      shortLabel:\"DB Administration\",\n      icon:\"dbadmin\",\n      photo:\"https:\/\/images.pexels.com\/photos\/17323801\/pexels-photo-17323801.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Database Administration service keeps the databases underpinning your business, from ERP and CRM to custom applications, performing reliably, securely, and predictably. We handle routine administration such as backups, patching, indexing, and performance tuning, along with capacity planning to ensure databases scale smoothly as data volumes grow.\",\n        \"When issues do arise, whether slow queries, failed jobs, or corruption risks, our team responds quickly to diagnose and resolve them, minimising impact on the systems that depend on that data. With proactive monitoring and documented maintenance routines, our database administration reduces the operational risk of running critical systems on ageing or poorly maintained databases.\"\n      ]\n    },\n    {\n      name:\"SharePoint\",\n      slug:\"svc-sharepoint\",\n      shortLabel:\"SharePoint\",\n      icon:\"share\",\n      photo:\"https:\/\/images.pexels.com\/photos\/32082430\/pexels-photo-32082430.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our SharePoint service helps businesses set up and structure SharePoint as a genuine hub for document management and internal collaboration, rather than an unused corner of Microsoft 365. We design site structures, permission models, and document libraries around how your teams actually need to share and find information, replacing scattered file shares and inconsistent versioning.\",\n        \"We also build out workflows, intranet-style team sites, and integrations with other Microsoft 365 tools to support day-to-day collaboration, along with training so staff adopt SharePoint properly rather than reverting to old habits. Ongoing support ensures the platform stays organised and secure as content and teams grow.\"\n      ]\n    },\n    {\n      name:\"Project Management\",\n      slug:\"svc-projectmanagement\",\n      shortLabel:\"Project Mgmt\",\n      icon:\"kanban\",\n      photo:\"https:\/\/images.pexels.com\/photos\/7693156\/pexels-photo-7693156.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"Our Project Management service brings structure and accountability to IT and systems projects, from initial scoping and planning through to delivery. We define clear milestones, resource plans, and risk registers upfront, then manage execution closely, coordinating internal teams, vendors, and stakeholders to keep projects on track and within budget.\",\n        \"Throughout delivery we maintain transparent communication, with regular status reporting so stakeholders always know where a project stands and what's coming next. Our approach is designed to catch scope creep and risks early, so projects are delivered against agreed outcomes rather than drifting, and the business sees real value from the investment.\"\n      ]\n    },\n    {\n      name:\"Microsoft CSP Services\",\n      slug:\"svc-mscsp\",\n      shortLabel:\"Microsoft CSP\",\n      icon:\"cloudcheck\",\n      photo:\"https:\/\/images.pexels.com\/photos\/5466238\/pexels-photo-5466238.jpeg?auto=compress&cs=tinysrgb&w=1600\",\n      desc:[\n        \"As a Microsoft Cloud Solution Provider, we manage the licensing, provisioning, and billing of Microsoft 365, Azure, and Dynamics services on your behalf, giving businesses a single point of contact instead of navigating Microsoft's licensing directly. We help identify the right licensing tier for your needs, avoiding both under-licensing risk and paying for capability you don't use.\",\n        \"Beyond licensing, our CSP relationship means we can provide direct, hands-on support for the Microsoft services you're subscribed to, backed by our own technical expertise rather than a generic support queue. As your needs evolve, we adjust licensing and services accordingly, keeping your Microsoft environment cost-effective and properly supported.\"\n      ]\n    }\n  ];\n\n  \/\/ ---- relevance groupings: shown on the inner ring; each expands to its\n  \/\/ members on the outer ring when tapped ----\n  var CATEGORY_DEFS = [\n    { name:\"Data & Databases\", shortName:\"Data & DB\", icon:\"database\",\n      slugs:[\"svc-database\",\"svc-dba\",\"svc-analytics\",\"svc-bi\"] },\n    { name:\"Security\", shortName:\"Security\", icon:\"shield\",\n      slugs:[\"svc-security\",\"svc-netsecurity\"] },\n    { name:\"Business Applications\", shortName:\"Biz Apps\", icon:\"grid\",\n      slugs:[\"svc-erp\",\"svc-crm\",\"svc-sharepoint\",\"svc-mscsp\"] },\n    { name:\"Infrastructure & Support\", shortName:\"Infra & Support\", icon:\"server\",\n      slugs:[\"svc-serversupport\",\"svc-desktopsupport\"] },\n    { name:\"Consulting & Delivery\", shortName:\"Consulting\", icon:\"flow\",\n      slugs:[\"svc-businessanalysis\",\"svc-training\",\"svc-projectmanagement\"] },\n    { name:\"Digital Development\", shortName:\"Digital Dev\", icon:\"code\",\n      slugs:[\"svc-web\"] }\n  ];\n\n  var CATEGORIES = CATEGORY_DEFS.map(function(c){\n    return {\n      name:c.name,\n      shortName:c.shortName,\n      icon:c.icon,\n      serviceIndices:c.slugs.map(function(slug){\n        return SERVICES.findIndex(function(s){ return s.slug === slug; });\n      })\n    };\n  });\n\n  var cogWrap = document.getElementById('cogWrap');\n  var cogNodesWrap = document.getElementById('cogNodes');\n  var cogConnectors = document.getElementById('cogConnectors');\n  var cogHub = document.getElementById('cogHub');\n  var cogHubStrong = document.getElementById('cogHubStrong');\n  var cogHubSpan = document.getElementById('cogHubSpan');\n  var overlay = document.getElementById('serviceOverlay');\n  var ambient = document.getElementById('serviceAmbient');\n  var backBtn = document.getElementById('serviceBack');\n  var progressEl = document.getElementById('serviceProgress');\n  var reelWrap = document.getElementById('serviceReel');\n  var menuCol = document.querySelector('.service-menu-col');\n  var contentCol = document.getElementById('serviceContentCol');\n  var card = document.getElementById('serviceCard');\n  var cardImage = document.getElementById('serviceCardImage');\n  var cardIcon = document.getElementById('serviceCardIcon');\n  var cardTitle = document.getElementById('serviceCardTitle');\n  var cardDesc = document.getElementById('serviceCardDesc');\n\n  var current = 0, isOpen = false, navLocked = false, activeCategory = -1;\n  var reelItems = [];\n  var ITEM_GAP = 46;\n  var TILT_STEP = 30;\n\n  \/\/ ---- build the inner (category) ring ----\n  var categoryNodeEls = [];\n  CATEGORIES.forEach(function(cat, ci){\n    var node = document.createElement('button');\n    node.className = 'cog-node cog-node--inner';\n    node.type = 'button';\n    node.dataset.categoryIndex = ci;\n    node.innerHTML = ICONS[cat.icon] + '<span class=\"cog-node__label\">' + cat.shortName + '<\/span>';\n    node.addEventListener('click', function(){ toggleCategory(ci); });\n    cogNodesWrap.appendChild(node);\n    categoryNodeEls.push(node);\n  });\n\n  \/\/ ---- build the outer (service) ring \u2014 hidden until their category is picked ----\n  var outerNodeEls = [];\n  SERVICES.forEach(function(s, si){\n    var node = document.createElement('button');\n    node.className = 'cog-node cog-node--outer';\n    node.type = 'button';\n    node.dataset.serviceIndex = si;\n    node.innerHTML = ICONS[s.icon] + '<span class=\"cog-node__label\">' + s.shortLabel + '<\/span>';\n    node.addEventListener('click', function(){ openServiceByIndex(si, true); });\n    cogNodesWrap.appendChild(node);\n    outerNodeEls.push(node);\n\n    var amb = document.createElement('div');\n    amb.className = 'service-ambient__layer';\n    amb.style.backgroundImage = \"url('\" + s.photo + \"')\";\n    ambient.appendChild(amb);\n  });\n  var scrim = document.createElement('div');\n  scrim.className = 'service-ambient__scrim';\n  ambient.appendChild(scrim);\n\n  var ambLayers = ambient.querySelectorAll('.service-ambient__layer');\n\n  function positionCategoryNodes(){\n    var cs = getComputedStyle(cogWrap);\n    var radiusInner = parseFloat(cs.getPropertyValue('--radius-inner')) || 150;\n    var step = 360 \/ categoryNodeEls.length;\n    categoryNodeEls.forEach(function(node, i){\n      var angle = (-90 + i * step) * Math.PI \/ 180;\n      var x = Math.cos(angle) * radiusInner;\n      var y = Math.sin(angle) * radiusInner;\n      node.style.setProperty('--tx', x.toFixed(1) + 'px');\n      node.style.setProperty('--ty', y.toFixed(1) + 'px');\n    });\n  }\n\n  function computeCategoryAngleDeg(catIdx){\n    var step = 360 \/ CATEGORIES.length;\n    return -90 + catIdx * step;\n  }\n\n  \/\/ Positions a category's services clustered in an arc near that category's\n  \/\/ own position (instead of spread evenly around the whole circle), and\n  \/\/ draws a glowing line from the category node out to each spawned service.\n  function updateOuterForCategory(catIdx){\n    var cs = getComputedStyle(cogWrap);\n    var radiusInner = parseFloat(cs.getPropertyValue('--radius-inner')) || 150;\n    var radiusOuter = parseFloat(cs.getPropertyValue('--radius-outer')) || 275;\n    var catAngleDeg = computeCategoryAngleDeg(catIdx);\n    var catRad = catAngleDeg * Math.PI \/ 180;\n    var catX = Math.cos(catRad) * radiusInner;\n    var catY = Math.sin(catRad) * radiusInner;\n\n    var memberIdxs = CATEGORIES[catIdx].serviceIndices;\n    var n = memberIdxs.length;\n    var spreadDeg = n <= 1 ? 0 : Math.min(56, 18 + (n - 1) * 16);\n    var startDeg = catAngleDeg - spreadDeg \/ 2;\n    var stepDeg = n > 1 ? spreadDeg \/ (n - 1) : 0;\n\n    var w = cogWrap.clientWidth;\n    var center = w \/ 2;\n    cogConnectors.setAttribute('viewBox', '0 0 ' + w + ' ' + w);\n    cogConnectors.innerHTML = '';\n\n    memberIdxs.forEach(function(svcIdx, i){\n      var angleDeg = startDeg + i * stepDeg;\n      var rad = angleDeg * Math.PI \/ 180;\n      var x = Math.cos(rad) * radiusOuter;\n      var y = Math.sin(rad) * radiusOuter;\n      var node = outerNodeEls[svcIdx];\n      node.style.setProperty('--tx', x.toFixed(1) + 'px');\n      node.style.setProperty('--ty', y.toFixed(1) + 'px');\n\n      var x1 = center + catX, y1 = center + catY, x2 = center + x, y2 = center + y;\n      var len = Math.hypot(x2 - x1, y2 - y1);\n      var line = document.createElementNS('http:\/\/www.w3.org\/2000\/svg', 'line');\n      line.setAttribute('x1', x1.toFixed(1));\n      line.setAttribute('y1', y1.toFixed(1));\n      line.setAttribute('x2', x2.toFixed(1));\n      line.setAttribute('y2', y2.toFixed(1));\n      line.style.strokeDasharray = len.toFixed(1);\n      line.style.strokeDashoffset = len.toFixed(1);\n      cogConnectors.appendChild(line);\n      \/\/ double rAF so the browser registers the starting dash offset\n      \/\/ before we animate it to 0 \u2014 otherwise it just snaps into place\n      requestAnimationFrame(function(){\n        requestAnimationFrame(function(){\n          line.classList.add('is-visible');\n          line.style.strokeDashoffset = '0';\n        });\n      });\n    });\n  }\n\n  positionCategoryNodes();\n  window.addEventListener('resize', function(){\n    positionCategoryNodes();\n    if(activeCategory > -1) updateOuterForCategory(activeCategory);\n  });\n\n  \/\/ ---- staggered entrance for the category ring when the section scrolls into view ----\n  if('IntersectionObserver' in window){\n    var seen = false;\n    var io = new IntersectionObserver(function(entries){\n      entries.forEach(function(entry){\n        if(entry.isIntersecting){\n          if(!seen){\n            seen = true;\n            categoryNodeEls.forEach(function(node, i){\n              setTimeout(function(){ node.classList.add('is-visible'); }, i * 70);\n            });\n            io.disconnect();\n          }\n        }\n      });\n    }, {threshold:0.35});\n    io.observe(cogWrap);\n  } else {\n    categoryNodeEls.forEach(function(n){ n.classList.add('is-visible'); });\n  }\n\n  \/\/ ---- subtle mouse-parallax tilt on the cog (desktop only) ----\n  var canHover = window.matchMedia('(hover:hover) and (pointer:fine)').matches;\n  if(canHover){\n    var rafId = null, targetRX = 0, targetRY = 0, curRX = 0, curRY = 0;\n    document.getElementById('servicesSection').addEventListener('mousemove', function(e){\n      var rect = cogWrap.getBoundingClientRect();\n      var cx = rect.left + rect.width \/ 2;\n      var cy = rect.top + rect.height \/ 2;\n      var dx = (e.clientX - cx) \/ (rect.width \/ 2);\n      var dy = (e.clientY - cy) \/ (rect.height \/ 2);\n      targetRY = Math.max(-1, Math.min(1, dx)) * 10;\n      targetRX = Math.max(-1, Math.min(1, dy)) * -10;\n      if(!rafId) rafId = requestAnimationFrame(tick);\n    });\n    document.getElementById('servicesSection').addEventListener('mouseleave', function(){\n      targetRX = 0; targetRY = 0;\n      if(!rafId) rafId = requestAnimationFrame(tick);\n    });\n    function tick(){\n      curRX += (targetRX - curRX) * 0.08;\n      curRY += (targetRY - curRY) * 0.08;\n      cogWrap.style.transform = 'rotateX(' + curRX.toFixed(2) + 'deg) rotateY(' + curRY.toFixed(2) + 'deg)';\n      if(Math.abs(targetRX - curRX) > 0.02 || Math.abs(targetRY - curRY) > 0.02){\n        rafId = requestAnimationFrame(tick);\n      } else {\n        rafId = null;\n      }\n    }\n  }\n\n  \/\/ ---- category selection: reveals that category's services on the outer ring ----\n  function activateCategory(catIdx){\n    activeCategory = catIdx;\n    var cat = CATEGORIES[catIdx];\n    var memberIdxs = cat.serviceIndices;\n\n    updateOuterForCategory(catIdx);\n    outerNodeEls.forEach(function(node, svcIdx){\n      node.classList.toggle('is-visible', memberIdxs.indexOf(svcIdx) > -1);\n    });\n    categoryNodeEls.forEach(function(node, i){\n      node.classList.toggle('is-active', i === catIdx);\n    });\n    cogWrap.classList.add('has-active');\n    cogHubStrong.textContent = cat.name;\n    cogHubSpan.textContent = 'Tap a service \u2014 or tap here to close';\n  }\n\n  function deselectCategory(){\n    activeCategory = -1;\n    cogConnectors.innerHTML = '';\n    outerNodeEls.forEach(function(node){ node.classList.remove('is-visible'); });\n    categoryNodeEls.forEach(function(node){ node.classList.remove('is-active'); });\n    cogWrap.classList.remove('has-active');\n    cogHubStrong.textContent = 'Services';\n    cogHubSpan.textContent = 'Tap an area to explore';\n  }\n\n  function toggleCategory(catIdx){\n    if(activeCategory === catIdx){ deselectCategory(); }\n    else{ activateCategory(catIdx); }\n  }\n\n  cogHub.addEventListener('click', function(){\n    if(activeCategory > -1) deselectCategory();\n  });\n\n  function findCategoryForService(svcIdx){\n    for(var i = 0; i < CATEGORIES.length; i++){\n      if(CATEGORIES[i].serviceIndices.indexOf(svcIdx) > -1) return i;\n    }\n    return -1;\n  }\n\n  \/\/ ---- shrink a reel label's font-size until its full row (icon + text + arrow)\n  \/\/ fits inside the available column width, so the mask never hard-clips it ----\n  function fitReelLabel(item, startRem, minRem, maxWidth){\n    var size = startRem;\n    item.style.fontSize = size + 'rem';\n    var guard = 0;\n    while(item.scrollWidth > maxWidth && size > minRem && guard < 30){\n      size -= 0.05;\n      item.style.fontSize = size.toFixed(2) + 'rem';\n      guard++;\n    }\n  }\n\n  \/\/ ---- build the reel's DOM to contain only the active category's services ----\n  function buildReelForCategory(catIdx){\n    reelWrap.innerHTML = '';\n    var memberIdxs = CATEGORIES[catIdx].serviceIndices;\n    memberIdxs.forEach(function(svcIdx, pos){\n      var s = SERVICES[svcIdx];\n      var reelItem = document.createElement('div');\n      reelItem.className = 'reel-item';\n      reelItem.innerHTML = ICONS[s.icon].replace('<svg ', '<svg class=\"reel-item__icon\" ') + '<span>' + s.shortLabel + '<\/span><span class=\"reel-item__arrow\">\\u2192<\/span>';\n      reelItem.addEventListener('click', function(){ showService(pos); });\n      reelWrap.appendChild(reelItem);\n    });\n    reelItems = reelWrap.querySelectorAll('.reel-item');\n  }\n\n  \/\/ ---- reel rendering: stacked, tilted, progressively blurred labels ----\n  function renderReel(){\n    var maxLabelWidth = (reelWrap.clientWidth || menuCol.clientWidth) - 16;\n    reelItems.forEach(function(item, i){\n      var offset = i - current;\n      var dist = Math.abs(offset);\n      var isFocus = dist === 0;\n\n      var scale = isFocus ? 1 : dist === 1 ? 0.68 : dist === 2 ? 0.55 : 0.46;\n      var opacity = isFocus ? 1 : dist === 1 ? 0.55 : dist === 2 ? 0.28 : dist === 3 ? 0.14 : 0;\n      var blur = isFocus ? 0 : dist === 1 ? 0.5 : dist === 2 ? 1.4 : 2.4;\n      var rotateX = isFocus ? 0 : Math.max(-64, Math.min(64, -offset * TILT_STEP));\n      var translateZ = isFocus ? 0 : -dist * 46;\n\n      item.classList.toggle('is-focus', isFocus);\n      fitReelLabel(item, isFocus ? 2.3 : 1.4, isFocus ? 1.1 : 0.85, maxLabelWidth);\n      item.style.transform =\n        'translateY(-50%) translateY(' + (offset * ITEM_GAP) + 'px) translateZ(' + translateZ + 'px) rotateX(' + rotateX + 'deg) scale(' + scale + ')';\n      item.style.opacity = opacity;\n      item.style.filter = 'blur(' + blur + 'px)';\n      item.style.zIndex = isFocus ? 5 : (10 - dist);\n      item.style.pointerEvents = dist > 3 ? 'none' : 'auto';\n    });\n  }\n\n  \/\/ ---- keep the content card inside its column, no scrollbars ever ----\n  function fitCardToContainer(){\n    var cs = getComputedStyle(contentCol);\n    var available = contentCol.clientHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom);\n    if(available <= 0) return;\n\n    card.style.maxHeight = available + 'px';\n    card.classList.remove('is-image-hidden');\n    card.style.setProperty('--fit-scale', 1);\n\n    var scale = 1;\n    var guard = 0;\n    var keepShrinking = true;\n    while(keepShrinking){\n      if(card.scrollHeight <= available + 1){ keepShrinking = false; }\n      if(guard >= 16){ keepShrinking = false; }\n      if(!keepShrinking){ break; }\n      scale -= 0.05;\n      if(scale <= 0.62){\n        if(!card.classList.contains('is-image-hidden')){\n          card.classList.add('is-image-hidden');\n        }\n      }\n      card.style.setProperty('--fit-scale', Math.max(scale, 0.44).toFixed(2));\n      guard++;\n    }\n  }\n\n  function onOverlayResize(){\n    renderReel();\n    fitCardToContainer();\n  }\n\n  \/\/ ---- overlay open \/ close ----\n  function openOverlay(pos, immediate){\n    isOpen = true;\n    overlay.classList.add('is-open');\n    overlay.setAttribute('aria-hidden', 'false');\n    document.body.style.overflow = 'hidden';\n    showService(pos, true);\n    menuCol.addEventListener('wheel', onWheel, {passive:false});\n    menuCol.addEventListener('touchstart', onTouchStart, {passive:true});\n    menuCol.addEventListener('touchend', onTouchEnd, {passive:true});\n    window.addEventListener('keydown', onKeydown);\n    window.addEventListener('resize', onOverlayResize);\n  }\n\n  \/\/ ---- single entry point: open a service by its global index, wherever it's triggered from ----\n  function openServiceByIndex(svcIdx, immediate){\n    var catIdx = findCategoryForService(svcIdx);\n    if(catIdx === -1) return;\n    activateCategory(catIdx);\n    buildReelForCategory(catIdx);\n    var pos = CATEGORIES[catIdx].serviceIndices.indexOf(svcIdx);\n    openOverlay(pos, immediate);\n  }\n\n  function closeService(){\n    isOpen = false;\n    overlay.classList.remove('is-open');\n    overlay.setAttribute('aria-hidden', 'true');\n    document.body.style.overflow = '';\n    menuCol.removeEventListener('wheel', onWheel);\n    menuCol.removeEventListener('touchstart', onTouchStart);\n    menuCol.removeEventListener('touchend', onTouchEnd);\n    window.removeEventListener('keydown', onKeydown);\n    window.removeEventListener('resize', onOverlayResize);\n    \/\/ the cog stays on the category the user came from \u2014 closing only leaves the overlay\n  }\n\n  function showService(pos, immediate){\n    if(activeCategory === -1) return;\n    var memberIdxs = CATEGORIES[activeCategory].serviceIndices;\n    current = Math.max(0, Math.min(memberIdxs.length - 1, pos));\n    var actualIdx = memberIdxs[current];\n    var s = SERVICES[actualIdx];\n\n    renderReel();\n    ambLayers.forEach(function(l, idx){ l.classList.toggle('is-active', idx === actualIdx); });\n    progressEl.innerHTML = '<b>' + String(current + 1).padStart(2,'0') + '<\/b> &nbsp;\\u2014&nbsp; ' + String(memberIdxs.length).padStart(2,'0') +\n      '<span class=\"service-progress__category\">' + CATEGORIES[activeCategory].name + '<\/span>';\n\n    var swap = function(){\n      cardImage.src = s.photo;\n      cardImage.alt = s.name;\n      cardIcon.innerHTML = ICONS[s.icon];\n      cardTitle.textContent = s.name;\n      cardDesc.innerHTML = s.desc.map(function(p){ return '<p>' + p + '<\/p>'; }).join('');\n      card.classList.add('is-visible');\n      fitCardToContainer();\n    };\n\n    if(immediate){\n      swap();\n    } else {\n      card.classList.remove('is-visible');\n      setTimeout(swap, 220);\n    }\n  }\n\n  backBtn.addEventListener('click', closeService);\n\n  \/\/ ---- scroll \/ keyboard \/ touch navigation while open (within the active category) ----\n  function nextService(){\n    var len = activeCategory > -1 ? CATEGORIES[activeCategory].serviceIndices.length : 0;\n    if(navLocked || current >= len - 1) return;\n    lockNav(); showService(current + 1);\n  }\n  function prevService(){ if(navLocked || current <= 0) return; lockNav(); showService(current - 1); }\n  function lockNav(){ navLocked = true; setTimeout(function(){ navLocked = false; }, 600); }\n\n  function onWheel(e){\n    if(!isOpen) return;\n    e.preventDefault();\n    if(Math.abs(e.deltaY) < 12) return;\n    if(e.deltaY > 0) nextService(); else prevService();\n  }\n\n  function onKeydown(e){\n    if(!isOpen) return;\n    if(e.key === 'ArrowDown'){ e.preventDefault(); nextService(); }\n    else if(e.key === 'ArrowUp'){ e.preventDefault(); prevService(); }\n    else if(e.key === 'Escape'){ closeService(); }\n  }\n\n  var touchStartY = null;\n  function onTouchStart(e){ touchStartY = e.touches[0].clientY; }\n  function onTouchEnd(e){\n    if(touchStartY === null) return;\n    var dy = touchStartY - e.changedTouches[0].clientY;\n    if(Math.abs(dy) > 40){ if(dy > 0) nextService(); else prevService(); }\n    touchStartY = null;\n  }\n\n  \/\/ ---- auto-open from footer\/deep links, e.g. #svc-database ----\n  function openFromHash(){\n    var hash = window.location.hash.replace('#','');\n    if(!hash) return false;\n    var idx = SERVICES.findIndex(function(s){ return s.slug === hash; });\n    if(idx > -1){ openServiceByIndex(idx, true); return true; }\n    return false;\n  }\n\n  \/\/ Try immediately, then again after full page load and shortly after \u2014\n  \/\/ some WP themes\/page builders finish rendering or intercept anchor\n  \/\/ navigation slightly after this inline script first runs.\n  openFromHash();\n  window.addEventListener('hashchange', openFromHash);\n  window.addEventListener('load', openFromHash);\n  setTimeout(openFromHash, 300);\n  setTimeout(openFromHash, 1000);\n\n  \/\/ Belt-and-braces: intercept clicks on any link pointing at a #svc-*\n  \/\/ fragment (e.g. footer quicklinks) directly, so this works even if a\n  \/\/ theme\/plugin swallows the native hash navigation or hashchange event,\n  \/\/ and even when clicked from a different page than services-2.\n  document.addEventListener('click', function(e){\n    var link = e.target.closest ? e.target.closest('a[href*=\"#svc-\"]') : null;\n    if(!link) return;\n    var hashIdx = link.href.indexOf('#');\n    if(hashIdx === -1) return;\n    var slug = link.href.slice(hashIdx + 1);\n    var idx = SERVICES.findIndex(function(s){ return s.slug === slug; });\n    if(idx === -1) return;\n\n    var samePage = link.pathname.replace(\/\\\/$\/, '') === window.location.pathname.replace(\/\\\/$\/, '');\n    if(samePage){\n      e.preventDefault();\n      if(window.location.hash !== '#' + slug){\n        history.pushState(null, '', '#' + slug);\n      }\n      openServiceByIndex(idx, true);\n    }\n    \/\/ If it's a different page, let the browser navigate normally \u2014\n    \/\/ the load\/setTimeout hash checks above will open it on arrival.\n  });\n})();\n<\/script>\n","protected":false},"excerpt":{"rendered":"<p>Our Services Our Services IT solutions built around your business Choose an area below, then explore how we design, secure, and scale the systems your business runs on. ServicesTap an area to explore Back Enquire About This Service \u2192 Scroll menu to browse<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"blank-canvas","meta":{"_gspb_post_css":"","om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"footnotes":""},"class_list":["post-387","page","type-page","status-publish","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/monichron.co.za\/index.php\/wp-json\/wp\/v2\/pages\/387","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/monichron.co.za\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/monichron.co.za\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/monichron.co.za\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/monichron.co.za\/index.php\/wp-json\/wp\/v2\/comments?post=387"}],"version-history":[{"count":15,"href":"https:\/\/monichron.co.za\/index.php\/wp-json\/wp\/v2\/pages\/387\/revisions"}],"predecessor-version":[{"id":489,"href":"https:\/\/monichron.co.za\/index.php\/wp-json\/wp\/v2\/pages\/387\/revisions\/489"}],"wp:attachment":[{"href":"https:\/\/monichron.co.za\/index.php\/wp-json\/wp\/v2\/media?parent=387"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}