PageSourceSearch

https://cto4ai.pages.dev/search/

html cto4ai.pages.dev collected 2026-10-03 06:38:19 UTC 26,148 bytes, 386 lines download raw bytes

1<!DOCTYPE html><html lang="en" dir="ltr" class="2xl:text-[20px]"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><link rel="sitemap" href="/sitemap-index.xml"><link rel="icon" type="image/svg+xml" href="/_astro/symbolBlack.BBmzdhP8.svg"><link rel="mask-icon" href="/_astro/symbolBlack.BBmzdhP8.svg" color="#8D46E7"><link rel="apple-touch-icon" sizes="180x180" href="/_astro/apple-touch-icon.BH5dQIYY.png"><style>
2  :root {
3    --aw-font-sans: 'Inter Variable';
4    --aw-font-serif: 'Inter Variable';
5    --aw-font-heading: 'Inter Variable';
6
7    --aw-color-primary: rgb(1 97 239);
8    --aw-color-secondary: rgb(1 84 207);
9    --aw-color-accent: rgb(109 40 217);
10
11    --aw-color-text-heading: rgb(0 0 0);
12    --aw-color-text-default: rgb(16 16 16);
13    --aw-color-text-muted: rgb(16 16 16 / 66%);
14    --aw-color-bg-page: rgb(255 255 255);
15
16    --aw-color-bg-page-dark: rgb(3 6 32);
17
18    ::selection {
19      background-color: lavender;
20    }
21  }
22
23  .dark {
24    --aw-font-sans: 'Inter Variable';
25    --aw-font-serif: 'Inter Variable';
26    --aw-font-heading: 'Inter Variable';
27
28    --aw-color-primary: rgb(1 97 239);
29    --aw-color-secondary: rgb(1 84 207);
30    --aw-color-accent: rgb(109 40 217);
31
32    --aw-color-text-heading: rgb(247, 248, 248);
33    --aw-color-text-default: rgb(229 236 246);
34    --aw-color-text-muted: rgb(229 236 246 / 66%);
35    --aw-color-bg-page: rgb(3 6 32);
36
37    ::selection {
38      background-color: black;
39      color: snow;
40    }
41  }
42
43  /* GLightbox inline slides (theme-native SVG diagrams): follow the page theme
44     instead of the library's hardcoded white background */
45  .glightbox-container .gslide-inline {
46    background: var(--aw-color-bg-page, #fff);
47  }
48</style>
48<script>(function(){const defaultTheme = "system";
49
50  function applyTheme(theme) {
51    if (theme === 'dark') {
52      document.documentElement.classList.add('dark');
53    } else {
54      document.documentElement.classList.remove('dark');
55    }
56    const matches = document.querySelectorAll('[data-aw-toggle-color-scheme] > input');
57
58    if (matches && matches.length) {
59      matches.forEach((elem) => {
60        elem.checked = theme !== 'dark';
61      });
62    }
63  }
64
65  if ((defaultTheme && defaultTheme.endsWith(':only')) || (!localStorage.theme && defaultTheme !== 'system')) {
66    applyTheme(defaultTheme.replace(':only', ''));
67  } else if (
68    localStorage.theme === 'dark' ||
69    (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
70  ) {
71    applyTheme('dark');
72  } else {
73    applyTheme('light');
74  }
75})();</script>
75<title>Search — cto4.ai</title>
76<meta name="description" content="Search through all blog posts, insights, and commentary">
77<meta name="robots" content="index,follow">
78<link rel="canonical" href="https://cto4.ai/search">
79<meta property="og:title" content="Search">
80<meta property="og:description" content="Search through all blog posts, insights, and commentary">
81<meta property="og:url" content="https://cto4.ai/search">
82<meta property="og:type" content="website">
83<meta property="og:image" content="https://cto4.ai/_astro/brand.kHOlry1h_ZlFGr2.jpg">
84<meta property="og:image:width" content="1200">
85<meta property="og:image:height" content="630">
86
87<meta property="og:locale" content="en">
88<meta property="og:site_name" content="cto4.ai">
89<meta name="twitter:card" content="summary_large_image">
90<meta name="twitter:site" content="@Jackivers">
91<meta name="twitter:creator" content="@Jackivers"><meta name="google-site-verification" content="orcPxI47GSa-cRvY11tUe6iGg2IO_RPvnA1q95iEM3M"><!-- Comment the line below to disable View Transitions --><meta name="astro-view-transitions-enabled" content="true"><meta name="astro-view-transitions-fallback" content="swap">
91<script type="module" src="/_astro/ClientRouter.astro_astro_type_script_index_0_lang.2i1RQzKf.js"></script>
91<style>.pagefind-ui{--pagefind-ui-scale:1;--pagefind-ui-primary:#3b82f6;--pagefind-ui-text:#374151;--pagefind-ui-background:#fff;--pagefind-ui-border:#d1d5db;--pagefind-ui-tag:#f3f4f6;--pagefind-ui-border-width:1px;--pagefind-ui-border-radius:.5rem}.dark .pagefind-ui{--pagefind-ui-text:#d1d5db;--pagefind-ui-background:#1f2937;--pagefind-ui-border:#374151;--pagefind-ui-tag:#374151}.pagefind-ui__search-input{border-radius:.5rem;padding:.75rem 1rem;font-size:1.125rem;color:#1f2937!important;background-color:#fff!important;border:2px solid #d1d5db!important}.pagefind-ui__search-input:focus{border-color:#3b82f6!important;outline:none!important;box-shadow:0 0 0 3px #3b82f61a!important}.pagefind-ui__search-input::placeholder{color:#6b7280!important}.dark .pagefind-ui__search-input{color:#f9fafb!important;background-color:#374151!important;border-color:#4b5563!important}.dark .pagefind-ui__search-input:focus{border-color:#60a5fa!important;box-shadow:0 0 0 3px #60a5fa1a!important}.dark .pagefind-ui__search-input::placeholder{color:#9ca3af!important}.pagefind-ui__result{border:1px solid var(--pagefind-ui-border);border-radius:.5rem;margin-bottom:1.5rem;padding:1rem}.pagefind-ui__result:hover{background-color:#f9fafb;border-color:#9ca3af}.dark .pagefind-ui__result:hover{background-color:#374151;border-color:#6b7280}.pagefind-ui__result-title{margin-bottom:.5rem;font-size:1.125rem;font-weight:600}.pagefind-ui__result-link{color:#1f2937;text-decoration:none}.dark .pagefind-ui__result-link{color:#f9fafb}.pagefind-ui__result-link:hover{color:#3b82f6}.pagefind-ui__result-excerpt{color:#6b7280;margin-bottom:.5rem;line-height:1.5}.dark .pagefind-ui__result-excerpt{color:#9ca3af}.pagefind-ui__result-nested{border-left:2px solid #e5e7eb;margin-top:.5rem;padding-left:1rem}.dark .pagefind-ui__result-nested{border-left-color:#4b5563}.pagefind-ui__result-nested-title{color:#6b7280;align-items:center;margin-bottom:.25rem;font-size:.875rem;display:inline-flex}.pagefind-ui__result-nested-title:before{content:"↪";margin-right:.5rem;font-size:.75rem}.dark .pagefind-ui__result-nested-title{color:#9ca3af}.pagefind-ui__result-tags{flex-wrap:wrap;gap:.5rem;margin-top:.5rem;display:flex}.pagefind-ui__result-tag{color:#6b7280;background-color:#f3f4f6;border-radius:.25rem;padding:.125rem .5rem;font-size:.75rem}.dark .pagefind-ui__result-tag{color:#9ca3af;background-color:#374151}.pagefind-ui__search-clear{color:#6b7280;cursor:pointer;background:0 0;border:none;padding:.5rem}.pagefind-ui__search-clear:hover{color:#374151}.dark .pagefind-ui__search-clear:hover{color:#d1d5db}
92</style><link rel="stylesheet" href="/_astro/Layout.DA15LbKO.css"><style>@font-face{font-family:Space Grotesk Variable;font-style:normal;font-display:swap;font-weight:300 700;src:url(/_astro/space-grotesk-vietnamese-wght-normal.D0rl6rjA.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Space Grotesk Variable;font-style:normal;font-display:swap;font-weight:300 700;src:url(/_astro/space-grotesk-latin-ext-wght-normal.D9tNdqV9.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Space Grotesk Variable;font-style:normal;font-display:swap;font-weight:300 700;src:url(/_astro/space-grotesk-latin-wght-normal.BhU9QXUp.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
93</style></head><body class="antialiased text-default bg-page tracking-tight">
94    <header class="sticky top-0 z-40 flex-none mx-auto w-full border-b border-gray-50/0 transition-[opacity] ease-in-out" data-aw-sticky-header="true" id="header" data-pagefind-ignore><div class="absolute inset-0"></div><div class="relative text-default py-3 px-3 md:px-6 mx-auto w-full md:grid md:grid-cols-3 md:items-center max-w-7xl"><div class="flex justify-between"><a class="flex items-center" href="/"><div class="flex items-center"><!-- Light mode: Use the color/black logo --><img src="/_astro/noBgColor.CUHb9rCV_1y0B2z.svg" alt="cto4.ai" loading="lazy" decoding="async" width="120" height="40" class="h-12 w-auto dark:hidden"><!-- Dark mode: Use the white logo --><img src="/_astro/noBgWhite.D-JT5cLu_1y0B2z.svg" alt="cto4.ai" loading="lazy" decoding="async" width="120" height="40" class="h-12 w-auto hidden dark:block"></div></a><div class="flex items-center md:hidden"><button type="button" class="flex flex-col h-12 w-12 rounded justify-center items-center cursor-pointer group" aria-label="Toggle Menu" data-aw-toggle-menu><span class="sr-only">Toggle Menu</span>
95    <span aria-hidden="true" class="h-0.5 w-6 my-1 rounded-full bg-black dark:bg-white transition ease transform duration-200 opacity-80 group-[.expanded]:rotate-45 group-[.expanded]:translate-y-2.5"></span>
96    <span aria-hidden="true" class="h-0.5 w-6 my-1 rounded-full bg-black dark:bg-white transition ease transform duration-200 opacity-80 group-[.expanded]:opacity-0"></span>
97    <span aria-hidden="true" class="h-0.5 w-6 my-1 rounded-full bg-black dark:bg-white transition ease transform duration-200 opacity-80 group-[.expanded]:-rotate-45 group-[.expanded]:-translate-y-2.5"></span>
98  </button></div></div><nav class="items-center w-full md:w-auto hidden md:flex md:mx-5 text-default overflow-y-auto overflow-x-hidden md:overflow-y-visible md:overflow-x-auto md:justify-self-center" aria-label="Main navigation"><ul class="flex flex-col md:flex-row md:self-center w-full md:w-auto text-xl md:text-[0.9375rem] tracking-[0.01rem] font-medium md:justify-center"><li class>
98<a class="hover:text-primary dark:hover:text-white px-4 py-3 flex items-center whitespace-nowrap" href="/">Home</a></li><li class><a class="hover:text-primary dark:hover:text-white px-4 py-3 flex items-center whitespace-nowrap" href="/archive">Archive</a></li><li class><a class="hover:text-primary dark:hover:text-white px-4 py-3 flex items-center whitespace-nowrap aw-link-active" href="/search">Search</a></li><li class><a class="hover:text-primary dark:hover:text-white px-4 py-3 flex items-center whitespace-nowrap" href="/services">Services</a></li><li class><a class="hover:text-primary dark:hover:text-white px-4 py-3 flex items-center whitespace-nowrap" href="/about">About</a></li></ul></nav><div class="hidden md:self-center md:flex items-center md:mb-0 fixed w-full md:w-auto md:static justify-end left-0 rtl:left-auto rtl:right-0 bottom-0 p-3 md:p-0 md:justify-self-end"><div class="items-center flex justify-between w-full md:w-auto"><div class="flex"><button type="button" class="text-muted dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center" aria-label="Toggle between Dark and Light mode" data-aw-toggle-color-scheme><svg width="1em" height="1em" class="w-6 h-6 md:w-5 md:h-5 md:inline-block" data-icon="tabler:sun"><symbol id="ai:tabler:sun" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 12a4 4 0 1 0 8 0a4 4 0 1 0-8 0m-5 0h1m8-9v1m8 8h1m-9 8v1M5.6 5.6l.7.7m12.1-.7l-.7.7m0 11.4l.7.7m-12.1-.7l-.7.7"/></symbol><use href="#ai:tabler:sun"></use></svg></button><a class="text-muted dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center" aria-label="RSS Feed" href="/rss.xml"><svg width="1em" height="1em" class="w-5 h-5" data-icon="tabler:rss"><symbol id="ai:tabler:rss" viewBox="0 0 24 24"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 19a1 1 0 1 0 2 0a1 1 0 1 0-2 0M4 4a16 16 0 0 1 16 16M4 11a9 9 0 0 1 9 9"/></symbol><use href="#ai:tabler:rss"></use></svg></a></div></div></div></div></header>
99  <main><section class="px-4 py-16 mx-auto max-w-6xl lg:px-8 lg:py-20" data-astro-cid-wp2l4cmv><div class="max-w-4xl mx-auto" data-astro-cid-wp2l4cmv><div id="search" class="w-full" data-astro-cid-wp2l4cmv></div></div></section></main>
100    <footer class="relative border-t border-gray-200 dark:border-slate-800 not-prose" data-pagefind-ignore><div class="dark:bg-dark absolute inset-0 pointer-events-none" aria-hidden="true"></div><div class="relative max-w-7xl mx-auto px-4 sm:px-6 dark:text-slate-300 intersect-once intersect-quarter intersect-no-queue motion-safe:md:opacity-0 motion-safe:md:intersect:animate-fade"><div class="grid grid-cols-12 gap-4 gap-y-8 sm:gap-8 py-8 md:py-12"><div class="col-span-12 lg:col-span-4"><div class="mb-2"><a class="inline-block font-bold text-xl" href="/">cto4.ai</a></div><div class="text-sm text-muted flex gap-1"></div></div><div class="col-span-6 md:col-span-3 lg:col-span-2"><div class="dark:text-gray-300 font-medium mb-2">Content</div><ul class="text-sm"><li class="mb-2"><a class="text-muted hover:text-gray-700 hover:underline dark:text-gray-400 transition duration-150 ease-in-out" href="/archive">Archive</a></li><li class="mb-2"><a class="text-muted hover:text-gray-700 hover:underline dark:text-gray-400 transition duration-150 ease-in-out" href="/rss.xml">RSS Feed</a></li></ul></div><div class="col-span-6 md:col-span-3 lg:col-span-2"><div class="dark:text-gray-300 font-medium mb-2">Services</div><ul class="text-sm"><li class="mb-2"><a class="text-muted hover:text-gray-700 hover:underline dark:text-gray-400 transition duration-150 ease-in-out" href="/services">Fractional CTO</a></li><li class="mb-2"><a class="text-muted hover:text-gray-700 hover:underline dark:text-gray-400 transition duration-150 ease-in-out" href="mailto:[email protected]">Contact</a></li></ul></div><div class="col-span-6 md:col-span-3 lg:col-span-2"><div class="dark:text-gray-300 font-medium mb-2">Company</div><ul class="text-sm"><li class="mb-2"><a class="text-muted hover:text-gray-700 hover:underline dark:text-gray-400 transition duration-150 ease-in-out" href="/about">About</a></li><li class="mb-2"><a class="text-muted hover:text-gray-700 hover:underline dark:text-gray-400 transition duration-150 ease-in-out" href="/privacy">Privacy Policy</a></li><li class="mb-2"><a class="text-muted hover:text-gray-700 hover:underline dark:text-gray-400 transition duration-150 ease-in-out" href="https://craftycto.com">CraftyCTO.com</a></li></ul></div></div><div class="md:flex md:items-center md:justify-between py-6 md:py-8"><ul class="flex mb-4 md:order-1 -ml-2 md:ml-4 md:mb-0 rtl:ml-0 rtl:-mr-2 rtl:md:ml-0 rtl:md:mr-4"><li><a class="text-muted dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-700 focus:outline-none focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-700 rounded-lg text-sm p-2.5 inline-flex items-center" aria-label="LinkedIn" href="https://www.linkedin.com/in/jackivers/"><svg width="1em" height="1em" class="w-5 h-5" data-icon="tabler:brand-linkedin">
100<symbol id="ai:tabler:brand-linkedin" viewBox="0 0 24 24"><g fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2"><path d="M8 11v5m0-8v.01M12 16v-5m4 5v-3a2 2 0 1 0-4 0"/><path d="M3 7a4 4 0 0 1 4-4h10a4 4 0 0 1 4 4v10a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4z"/></g></symbol><use href="#ai:tabler:brand-linkedin"></use></svg></a></li></ul><div class="text-sm mr-4 dark:text-muted">
101    Copyright 2019-2026 <a class="text-blue-600 underline dark:text-muted" href="https://craftycto.com"> Crafty CTO</a> · All rights reserved.
102  </div></div></div></footer>
103  
103<script>(function(){const defaultTheme = "system";
104
105  (function () {
106    if (window.basic_script) {
107      return;
108    }
109
110    window.basic_script = true;
111
112    function applyTheme(theme) {
113      if (theme === 'dark') {
114        document.documentElement.classList.add('dark');
115      } else {
116        document.documentElement.classList.remove('dark');
117      }
118    }
119
120    const initTheme = function () {
121      if ((defaultTheme && defaultTheme.endsWith(':only')) || (!localStorage.theme && defaultTheme !== 'system')) {
122        applyTheme(defaultTheme.replace(':only', ''));
123      } else if (
124        localStorage.theme === 'dark' ||
125        (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
126      ) {
127        applyTheme('dark');
128      } else {
129        applyTheme('light');
130      }
131    };
132    initTheme();
133
134    function attachEvent(selector, event, fn) {
135      const matches = typeof selector === 'string' ? document.querySelectorAll(selector) : selector;
136      if (matches && matches.length) {
137        matches.forEach((elem) => {
138          elem.addEventListener(event, (e) => fn(e, elem), false);
139        });
140      }
141    }
142
143    const onLoad = function () {
144      let lastKnownScrollPosition = window.scrollY;
145      let ticking = true;
146
147      attachEvent('#header nav', 'click', function () {
148        document.querySelector('[data-aw-toggle-menu]')?.classList.remove('expanded');
149        document.body.classList.remove('overflow-hidden');
150        document.getElementById('header')?.classList.remove('h-screen');
151        document.getElementById('header')?.classList.remove('expanded');
152        document.getElementById('header')?.classList.remove('bg-page');
153        document.querySelector('#header nav')?.classList.add('hidden');
154        document.querySelector('#header > div > div:last-child')?.classList.add('hidden');
155      });
156
157      attachEvent('[data-aw-toggle-menu]', 'click', function (_, elem) {
158        elem.classList.toggle('expanded');
159        document.body.classList.toggle('overflow-hidden');
160        document.getElementById('header')?.classList.toggle('h-screen');
161        document.getElementById('header')?.classList.toggle('expanded');
162        document.getElementById('header')?.classList.toggle('bg-page');
163        document.querySelector('#header nav')?.classList.toggle('hidden');
164        document.querySelector('#header > div > div:last-child')?.classList.toggle('hidden');
165      });
166
167      attachEvent('[data-aw-toggle-color-scheme]', 'click', function () {
168        if (defaultTheme.endsWith(':only')) {
169          return;
170        }
171        document.documentElement.classList.toggle('dark');
172        localStorage.theme = document.documentElement.classList.contains('dark') ? 'dark' : 'light';
173      });
174
175      attachEvent('[data-aw-social-share]', 'click', function (_, elem) {
176        const network = elem.getAttribute('data-aw-social-share');
177        const url = encodeURIComponent(elem.getAttribute('data-aw-url'));
178        const text = encodeURIComponent(elem.getAttribute('data-aw-text'));
179
180        let href;
181        switch (network) {
182          case 'facebook':
183            href = `https://www.facebook.com/sharer.php?u=${url}`;
184            break;
185          case 'twitter':
186            href = `https://twitter.com/intent/tweet?url=${url}&text=${text}`;
187            break;
188          case 'linkedin':
189            href = `https://www.linkedin.com/shareArticle?mini=true&url=${url}&title=${text}`;
190            break;
191          case 'whatsapp':
192            href = `https://wa.me/?text=${text}%20${url}`;
193            break;
194          case 'mail':
195            href = `mailto:?subject=%22${text}%22&body=${text}%20${url}`;
196            break;
197
198          default:
199            return;
200        }
201
202        const newlink = document.createElement('a');
203        newlink.target = '_blank';
204        newlink.href = href;
205        newlink.click();
206      });
207
208      const screenSize = window.matchMedia('(max-width: 767px)');
209      screenSize.addEventListener('change', function () {
210        document.querySelector('[data-aw-toggle-menu]')?.classList.remove('expanded');
211        document.body.classList.remove('overflow-hidden');
212        document.getElementById('header')?.classList.remove('h-screen');
213        document.getElementById('header')?.classList.remove('expanded');
214        document.getElementById('header')?.classList.remove('bg-page');
215        document.querySelector('#header nav')?.classList.add('hidden');
216        document.querySelector('#header > div > div:last-child')?.classList.add('hidden');
217      });
218
219      function applyHeaderStylesOnScroll() {
220        const header = document.querySelector('#header[data-aw-sticky-header]');
221        if (!header) return;
222        if (lastKnownScrollPosition > 60 && !header.classList.contains('scroll')) {
223          header.classList.add('scroll');
224        } else if (lastKnownScrollPosition <= 60 && header.classList.contains('scroll')) {
225          header.classList.remove('scroll');
226        }
227        ticking = false;
228      }
229      applyHeaderStylesOnScroll();
230
231      attachEvent([document], 'scroll', function () {
232        lastKnownScrollPosition = window.scrollY;
233
234        if (!ticking) {
235          window.requestAnimationFrame(() => {
236            applyHeaderStylesOnScroll();
237          });
238          ticking = true;
239        }
240      });
241      // Handle anchor link clicks for proper positioning with sticky header
242      attachEvent('a[href^="#"]', 'click', function (e, elem) {
243        const targetId = elem.getAttribute('href').slice(1);
244        if (!targetId) return;
245
246        const targetElement = document.getElementById(targetId);
247        if (!targetElement) return;
248
249        e.preventDefault();
250
251        // Temporarily disable smooth scrolling for precise positioning
252        document.documentElement.style.scrollBehavior = 'auto';
253
254        // Calculate position accounting for sticky header
255        const headerHeight = 96; // Header height
256        const offset = 20; // Additional offset for better visual spacing
257        const elementPosition = targetElement.getBoundingClientRect().top;
258        const offsetPosition = elementPosition + window.pageYOffset - headerHeight - offset;
259
260        window.scrollTo({
261          top: offsetPosition,
262          behavior: 'auto',
263        });
264
265        // Update URL hash
266        history.pushState(null, null, '#' + targetId);
267
268        // Re-enable smooth scrolling after a brief delay
269        setTimeout(() => {
270          document.documentElement.style.scrollBehavior = '';
271        }, 100);
272      });
273    };
274    const onPageShow = function () {
275      document.documentElement.classList.add('motion-safe:scroll-smooth');
276      const elem = document.querySelector('[data-aw-toggle-menu]');
277      if (elem) {
278        elem.classList.remove('expanded');
279      }
280      document.body.classList.remove('overflow-hidden');
281      document.getElementById('header')?.classList.remove('h-screen');
282      document.getElementById('header')?.classList.remove('expanded');
283      document.querySelector('#header nav')?.classList.add('hidden');
284    };
285
286    window.onload = onLoad;
287    window.onpageshow = onPageShow;
288
289    document.addEventListener('astro:after-swap', () => {
290      initTheme();
291      onLoad();
292      onPageShow();
293    });
294  })();
295})();</script>
295<script>
296  /* Inspired by: https://github.com/heidkaemper/tailwindcss-intersect */
297  const Observer = {
298    observer: null,
299    delayBetweenAnimations: 100,
300    animationCounter: 0,
301
302    start() {
303      const selectors = [
304        '[class*=" intersect:"]',
305        '[class*=":intersect:"]',
306        '[class^="intersect:"]',
307        '[class="intersect"]',
308        '[class*=" intersect "]',
309        '[class^="intersect "]',
310        '[class$=" intersect"]',
311      ];
312
313      const elements = Array.from(document.querySelectorAll(selectors.join(',')));
314
315      const getThreshold = (element) => {
316        if (element.classList.contains('intersect-full')) return 0.99;
317        if (element.classList.contains('intersect-half')) return 0.5;
318        if (element.classList.contains('intersect-quarter')) return 0.25;
319        return 0;
320      };
321
322      elements.forEach((el) => {
323        el.setAttribute('no-intersect', '');
324        el._intersectionThreshold = getThreshold(el);
325      });
326
327      const callback = (entries) => {
328        entries.forEach((entry) => {
329          requestAnimationFrame(() => {
330            const target = entry.target;
331            const intersectionRatio = entry.intersectionRatio;
332            const threshold = target._intersectionThreshold;
333
334            if (target.classList.contains('intersect-no-queue')) {
335              if (entry.isIntersecting) {
336                target.removeAttribute('no-intersect');
337                if (target.classList.contains('intersect-once')) {
338                  this.observer.unobserve(target);
339                }
340              } else {
341                target.setAttribute('no-intersect', '');
342              }
343              return;
344            }
345
346            if (intersectionRatio >= threshold) {
347              if (!target.hasAttribute('data-animated')) {
348                target.removeAttribute('no-intersect');
349                target.setAttribute('data-animated', 'true');
350
351                const delay = this.animationCounter * this.delayBetweenAnimations;
352                this.animationCounter++;
353
354                target.style.transitionDelay = `${delay}ms`;
355                target.style.animationDelay = `${delay}ms`;
356
357                if (target.classList.contains('intersect-once')) {
358                  this.observer.unobserve(target);
359                }
360              }
361            } else {
362              target.setAttribute('no-intersect', '');
363              target.removeAttribute('data-animated');
364              target.style.transitionDelay = '';
365              target.style.animationDelay = '';
366
367              this.animationCounter = 0;
368            }
369          });
370        });
371      };
372
373      this.observer = new IntersectionObserver(callback.bind(this), { threshold: [0, 0.25, 0.5, 0.99] });
374
375      elements.forEach((el) => {
376        this.observer.observe(el);
377      });
378    },
379  };
380
381  Observer.start();
382
383  document.addEventListener('astro:after-swap', () => {
384    Observer.start();
385  });
386</script>
386<!-- Global Lightbox Manager -->
386<script type="module" src="/_astro/Layout.astro_astro_type_script_index_0_lang.DIVGY2Yd.js"></script>
386</body></html>
386<script type="module" src="/_astro/search.astro_astro_type_script_index_0_lang.1yqxcU8t.js"></script>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.