Repository files navigation

ikeanalytics.com - personal site

A small static site for Isaac Liem at ikeanalytics.com. Built with Astro and the same Ike color brands and component vocabulary that ship in PSP. The site is authored as markdown articles served as a true static dist/, hosted on a Raspberry Pi 5 behind a Cloudflare Tunnel.

Quick start

npm install
npm run dev # dev server on http://localhost:4321 (hot reload)
npm run build # static dist/
npm run preview # serves dist/ on http://localhost:4321

Project layout

ikeanalytics-com/
├── astro.config.mjs # integrations: tailwind, sitemap, mdx
├── tailwind.config.js # Ike palette (gold / red / teal)
├── src/
│ ├── styles/globals.css # ike-card, ike-btn-*, text-gradient-*, glass
│ ├── content/blog/ # markdown articles
│ ├── components/ # Nav, Footer, Hero, ArticleCard, SocialLinks
│ ├── layouts/ # BaseLayout.astro (head, JSON-LD, RSS)
│ └── pages/ # /, /articles, /articles/[...slug], /about, /now, /404
├── public/brand/ # logos (decoupled from PSP)
└── deploy/ # nginx + cloudflared configs + deploy script

Authoring an article

Drop a markdown file into src/content/blog/:

---title: "Your title"description: "One-sentence summary that goes in OG, RSS, and the meta description."pubDate: 2026-07-15tags: ["aip", "protocols"]---
Body in markdown. Headings, lists, code blocks all work. The article URL is
auto-generated from the filename (`your-title.md``/articles/your-title/`).

Frontmatter is validated by the Zod schema in src/content/config.ts. The homepage and /articles index pick the new post up automatically on the next build.

Deploy

The site is static. dist/ ships to the Pi, nginx serves it on 127.0.0.1:8080, and cloudflared tunnels public traffic to that port. The Pi does not need a public IP - cloudflared opens an outbound TCP 443 connection to Cloudflare's edge.

./deploy/deploy.ps1 # target comes from deploy/pi-host.txt (see deploy.ps1)

That runs npm run build, scp -r dist/* to the Pi, and reloads nginx. The Pi's nginx config is in deploy/nginx-ikeanalytics.com.conf - install it at /etc/nginx/sites-available/ikeanalytics.com and symlink to sites-enabled/. The Cloudflare Tunnel config is in deploy/cloudflared-config.yml.example - see the comments in that file for the one-time setup (cloudflared tunnel login, tunnel create, tunnel route dns, service install).

Auth: SSH key only. The Pi's pi user must have your public key in ~/.ssh/authorized_keys. The deploy script defaults to $env:USERPROFILE\.ssh\id_ed25519; pass -SshKey <path> to override.

The Ike color brands

From the PSP design system, with PSP-specific shims removed:

TokenHexUse
ike-gold#D4A017Primary surface accent
ike-gold-light#E8C547Hover state
ike-gold-dark#A07810Deep accent
ike-red#C41E3ASignal - personal data boundary, accent bar
ike-teal#1A9B8AVerified / live / coordinated state
surface-dark#0D0D0DCanvas
surface-card#141414Card surface
surface-border#2A2A2AHairline borders

Component classes: ike-card, ike-card-gold/teal/red, ike-btn-gold/red/ghost, ike-label, ike-badge-gold/teal/red, text-gradient-gold, text-gradient-ike, glass, ike-accent-bar, ike-accent-bar-gold.

Fonts: Inter (sans), Syne (display), JetBrains Mono (mono). Loaded once via Google Fonts in BaseLayout.astro.

Constraints

  • No employer name anywhere. This is a public constraint inherited from the AIP launch state - see about.astro and the article copy.
  • AIP is a brand, Ike Analytics is a brand, this site is the Ike Analytics surface. The protocol has its own surface (the GitHub repo + whitepaper). Don't conflate them in copy. The footer carries an "Apache-2.0" tag near the AIP link as a reminder that the protocol is openly licensed for adoption.
  • Dark-only. No light mode. This matches PSP and the protocol aesthetic.

License

This site is the personal surface for Isaac Liem. The article text and the site code are © Isaac Liem. The AIP protocol is dual-licensed: the spec is under CC BY 4.0 and the reference implementation is under Apache License 2.0 - the most adoption-friendly strong-copyleft that's still open source by the OSI, with the explicit patent grant. See github.com/githubscum/aip-protocol. ike OS (the reference runtime that ships AIP) is under AGPL-3.0-or-later; see github.com/githubscum/psp. The protocol and the runtime are licensed differently on purpose: AIP is meant to be adopted by anyone, including closed-source products, while ike OS itself stays copyleft to keep forks of the runtime accountable.

About

ikeanalytics.com - Astro site, dark editorial system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Repository files navigation

ikeanalytics.com - personal site

A small static site for Isaac Liem at ikeanalytics.com. Built with Astro and the same Ike color brands and component vocabulary that ship in PSP. The site is authored as markdown articles served as a true static dist/, hosted on a Raspberry Pi 5 behind a Cloudflare Tunnel.

Quick start

npm install
npm run dev # dev server on http://localhost:4321 (hot reload)
npm run build # static dist/
npm run preview # serves dist/ on http://localhost:4321

Project layout

ikeanalytics-com/
├── astro.config.mjs # integrations: tailwind, sitemap, mdx
├── tailwind.config.js # Ike palette (gold / red / teal)
├── src/
│ ├── styles/globals.css # ike-card, ike-btn-*, text-gradient-*, glass
│ ├── content/blog/ # markdown articles
│ ├── components/ # Nav, Footer, Hero, ArticleCard, SocialLinks
│ ├── layouts/ # BaseLayout.astro (head, JSON-LD, RSS)
│ └── pages/ # /, /articles, /articles/[...slug], /about, /now, /404
├── public/brand/ # logos (decoupled from PSP)
└── deploy/ # nginx + cloudflared configs + deploy script

Authoring an article

Drop a markdown file into src/content/blog/:

---title: "Your title"description: "One-sentence summary that goes in OG, RSS, and the meta description."pubDate: 2026-07-15tags: ["aip", "protocols"]---
Body in markdown. Headings, lists, code blocks all work. The article URL is
auto-generated from the filename (`your-title.md``/articles/your-title/`).

Frontmatter is validated by the Zod schema in src/content/config.ts. The homepage and /articles index pick the new post up automatically on the next build.

Deploy

The site is static. dist/ ships to the Pi, nginx serves it on 127.0.0.1:8080, and cloudflared tunnels public traffic to that port. The Pi does not need a public IP - cloudflared opens an outbound TCP 443 connection to Cloudflare's edge.

./deploy/deploy.ps1 # target comes from deploy/pi-host.txt (see deploy.ps1)

That runs npm run build, scp -r dist/* to the Pi, and reloads nginx. The Pi's nginx config is in deploy/nginx-ikeanalytics.com.conf - install it at /etc/nginx/sites-available/ikeanalytics.com and symlink to sites-enabled/. The Cloudflare Tunnel config is in deploy/cloudflared-config.yml.example - see the comments in that file for the one-time setup (cloudflared tunnel login, tunnel create, tunnel route dns, service install).

Auth: SSH key only. The Pi's pi user must have your public key in ~/.ssh/authorized_keys. The deploy script defaults to $env:USERPROFILE\.ssh\id_ed25519; pass -SshKey <path> to override.

The Ike color brands

From the PSP design system, with PSP-specific shims removed:

TokenHexUse
ike-gold#D4A017Primary surface accent
ike-gold-light#E8C547Hover state
ike-gold-dark#A07810Deep accent
ike-red#C41E3ASignal - personal data boundary, accent bar
ike-teal#1A9B8AVerified / live / coordinated state
surface-dark#0D0D0DCanvas
surface-card#141414Card surface
surface-border#2A2A2AHairline borders

Component classes: ike-card, ike-card-gold/teal/red, ike-btn-gold/red/ghost, ike-label, ike-badge-gold/teal/red, text-gradient-gold, text-gradient-ike, glass, ike-accent-bar, ike-accent-bar-gold.

Fonts: Inter (sans), Syne (display), JetBrains Mono (mono). Loaded once via Google Fonts in BaseLayout.astro.

Constraints

  • No employer name anywhere. This is a public constraint inherited from the AIP launch state - see about.astro and the article copy.
  • AIP is a brand, Ike Analytics is a brand, this site is the Ike Analytics surface. The protocol has its own surface (the GitHub repo + whitepaper). Don't conflate them in copy. The footer carries an "Apache-2.0" tag near the AIP link as a reminder that the protocol is openly licensed for adoption.
  • Dark-only. No light mode. This matches PSP and the protocol aesthetic.

License

This site is the personal surface for Isaac Liem. The article text and the site code are © Isaac Liem. The AIP protocol is dual-licensed: the spec is under CC BY 4.0 and the reference implementation is under Apache License 2.0 - the most adoption-friendly strong-copyleft that's still open source by the OSI, with the explicit patent grant. See github.com/githubscum/aip-protocol. ike OS (the reference runtime that ships AIP) is under AGPL-3.0-or-later; see github.com/githubscum/psp. The protocol and the runtime are licensed differently on purpose: AIP is meant to be adopted by anyone, including closed-source products, while ike OS itself stays copyleft to keep forks of the runtime accountable.

About

ikeanalytics.com - Astro site, dark editorial system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ikeanalytics.com - personal site

A small static site for Isaac Liem at ikeanalytics.com. Built with Astro and the same Ike color brands and component vocabulary that ship in PSP. The site is authored as markdown articles served as a true static dist/, hosted on a Raspberry Pi 5 behind a Cloudflare Tunnel.

Quick start

npm install
npm run dev # dev server on http://localhost:4321 (hot reload)
npm run build # static dist/
npm run preview # serves dist/ on http://localhost:4321

Project layout

ikeanalytics-com/
├── astro.config.mjs # integrations: tailwind, sitemap, mdx
├── tailwind.config.js # Ike palette (gold / red / teal)
├── src/
│ ├── styles/globals.css # ike-card, ike-btn-*, text-gradient-*, glass
│ ├── content/blog/ # markdown articles
│ ├── components/ # Nav, Footer, Hero, ArticleCard, SocialLinks
│ ├── layouts/ # BaseLayout.astro (head, JSON-LD, RSS)
│ └── pages/ # /, /articles, /articles/[...slug], /about, /now, /404
├── public/brand/ # logos (decoupled from PSP)
└── deploy/ # nginx + cloudflared configs + deploy script

Authoring an article

Drop a markdown file into src/content/blog/:

---title: "Your title"description: "One-sentence summary that goes in OG, RSS, and the meta description."pubDate: 2026-07-15tags: ["aip", "protocols"]---
Body in markdown. Headings, lists, code blocks all work. The article URL is
auto-generated from the filename (`your-title.md``/articles/your-title/`).

Frontmatter is validated by the Zod schema in src/content/config.ts. The homepage and /articles index pick the new post up automatically on the next build.

Deploy

The site is static. dist/ ships to the Pi, nginx serves it on 127.0.0.1:8080, and cloudflared tunnels public traffic to that port. The Pi does not need a public IP - cloudflared opens an outbound TCP 443 connection to Cloudflare's edge.

./deploy/deploy.ps1 # target comes from deploy/pi-host.txt (see deploy.ps1)

That runs npm run build, scp -r dist/* to the Pi, and reloads nginx. The Pi's nginx config is in deploy/nginx-ikeanalytics.com.conf - install it at /etc/nginx/sites-available/ikeanalytics.com and symlink to sites-enabled/. The Cloudflare Tunnel config is in deploy/cloudflared-config.yml.example - see the comments in that file for the one-time setup (cloudflared tunnel login, tunnel create, tunnel route dns, service install).

Auth: SSH key only. The Pi's pi user must have your public key in ~/.ssh/authorized_keys. The deploy script defaults to $env:USERPROFILE\.ssh\id_ed25519; pass -SshKey <path> to override.

The Ike color brands

From the PSP design system, with PSP-specific shims removed:

TokenHexUse
ike-gold#D4A017Primary surface accent
ike-gold-light#E8C547Hover state
ike-gold-dark#A07810Deep accent
ike-red#C41E3ASignal - personal data boundary, accent bar
ike-teal#1A9B8AVerified / live / coordinated state
surface-dark#0D0D0DCanvas
surface-card#141414Card surface
surface-border#2A2A2AHairline borders

Component classes: ike-card, ike-card-gold/teal/red, ike-btn-gold/red/ghost, ike-label, ike-badge-gold/teal/red, text-gradient-gold, text-gradient-ike, glass, ike-accent-bar, ike-accent-bar-gold.

Fonts: Inter (sans), Syne (display), JetBrains Mono (mono). Loaded once via Google Fonts in BaseLayout.astro.

Constraints

  • No employer name anywhere. This is a public constraint inherited from the AIP launch state - see about.astro and the article copy.
  • AIP is a brand, Ike Analytics is a brand, this site is the Ike Analytics surface. The protocol has its own surface (the GitHub repo + whitepaper). Don't conflate them in copy. The footer carries an "Apache-2.0" tag near the AIP link as a reminder that the protocol is openly licensed for adoption.
  • Dark-only. No light mode. This matches PSP and the protocol aesthetic.

License

This site is the personal surface for Isaac Liem. The article text and the site code are © Isaac Liem. The AIP protocol is dual-licensed: the spec is under CC BY 4.0 and the reference implementation is under Apache License 2.0 - the most adoption-friendly strong-copyleft that's still open source by the OSI, with the explicit patent grant. See github.com/githubscum/aip-protocol. ike OS (the reference runtime that ships AIP) is under AGPL-3.0-or-later; see github.com/githubscum/psp. The protocol and the runtime are licensed differently on purpose: AIP is meant to be adopted by anyone, including closed-source products, while ike OS itself stays copyleft to keep forks of the runtime accountable.

About

ikeanalytics.com - Astro site, dark editorial system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ikeanalytics.com - personal site

A small static site for Isaac Liem at ikeanalytics.com. Built with Astro and the same Ike color brands and component vocabulary that ship in PSP. The site is authored as markdown articles served as a true static dist/, hosted on a Raspberry Pi 5 behind a Cloudflare Tunnel.

Quick start

npm install
npm run dev # dev server on http://localhost:4321 (hot reload)
npm run build # static dist/
npm run preview # serves dist/ on http://localhost:4321

Project layout

ikeanalytics-com/
├── astro.config.mjs # integrations: tailwind, sitemap, mdx
├── tailwind.config.js # Ike palette (gold / red / teal)
├── src/
│ ├── styles/globals.css # ike-card, ike-btn-*, text-gradient-*, glass
│ ├── content/blog/ # markdown articles
│ ├── components/ # Nav, Footer, Hero, ArticleCard, SocialLinks
│ ├── layouts/ # BaseLayout.astro (head, JSON-LD, RSS)
│ └── pages/ # /, /articles, /articles/[...slug], /about, /now, /404
├── public/brand/ # logos (decoupled from PSP)
└── deploy/ # nginx + cloudflared configs + deploy script

Authoring an article

Drop a markdown file into src/content/blog/:

---title: "Your title"description: "One-sentence summary that goes in OG, RSS, and the meta description."pubDate: 2026-07-15tags: ["aip", "protocols"]---
Body in markdown. Headings, lists, code blocks all work. The article URL is
auto-generated from the filename (`your-title.md``/articles/your-title/`).

Frontmatter is validated by the Zod schema in src/content/config.ts. The homepage and /articles index pick the new post up automatically on the next build.

Deploy

The site is static. dist/ ships to the Pi, nginx serves it on 127.0.0.1:8080, and cloudflared tunnels public traffic to that port. The Pi does not need a public IP - cloudflared opens an outbound TCP 443 connection to Cloudflare's edge.

./deploy/deploy.ps1 # target comes from deploy/pi-host.txt (see deploy.ps1)

That runs npm run build, scp -r dist/* to the Pi, and reloads nginx. The Pi's nginx config is in deploy/nginx-ikeanalytics.com.conf - install it at /etc/nginx/sites-available/ikeanalytics.com and symlink to sites-enabled/. The Cloudflare Tunnel config is in deploy/cloudflared-config.yml.example - see the comments in that file for the one-time setup (cloudflared tunnel login, tunnel create, tunnel route dns, service install).

Auth: SSH key only. The Pi's pi user must have your public key in ~/.ssh/authorized_keys. The deploy script defaults to $env:USERPROFILE\.ssh\id_ed25519; pass -SshKey <path> to override.

The Ike color brands

From the PSP design system, with PSP-specific shims removed:

TokenHexUse
ike-gold#D4A017Primary surface accent
ike-gold-light#E8C547Hover state
ike-gold-dark#A07810Deep accent
ike-red#C41E3ASignal - personal data boundary, accent bar
ike-teal#1A9B8AVerified / live / coordinated state
surface-dark#0D0D0DCanvas
surface-card#141414Card surface
surface-border#2A2A2AHairline borders

Component classes: ike-card, ike-card-gold/teal/red, ike-btn-gold/red/ghost, ike-label, ike-badge-gold/teal/red, text-gradient-gold, text-gradient-ike, glass, ike-accent-bar, ike-accent-bar-gold.

Fonts: Inter (sans), Syne (display), JetBrains Mono (mono). Loaded once via Google Fonts in BaseLayout.astro.

Constraints

  • No employer name anywhere. This is a public constraint inherited from the AIP launch state - see about.astro and the article copy.
  • AIP is a brand, Ike Analytics is a brand, this site is the Ike Analytics surface. The protocol has its own surface (the GitHub repo + whitepaper). Don't conflate them in copy. The footer carries an "Apache-2.0" tag near the AIP link as a reminder that the protocol is openly licensed for adoption.
  • Dark-only. No light mode. This matches PSP and the protocol aesthetic.

License

This site is the personal surface for Isaac Liem. The article text and the site code are © Isaac Liem. The AIP protocol is dual-licensed: the spec is under CC BY 4.0 and the reference implementation is under Apache License 2.0 - the most adoption-friendly strong-copyleft that's still open source by the OSI, with the explicit patent grant. See github.com/githubscum/aip-protocol. ike OS (the reference runtime that ships AIP) is under AGPL-3.0-or-later; see github.com/githubscum/psp. The protocol and the runtime are licensed differently on purpose: AIP is meant to be adopted by anyone, including closed-source products, while ike OS itself stays copyleft to keep forks of the runtime accountable.

About

ikeanalytics.com - Astro site, dark editorial system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Repository files navigation

ikeanalytics.com - personal site

A small static site for Isaac Liem at ikeanalytics.com. Built with Astro and the same Ike color brands and component vocabulary that ship in PSP. The site is authored as markdown articles served as a true static dist/, hosted on a Raspberry Pi 5 behind a Cloudflare Tunnel.

Quick start

npm install
npm run dev # dev server on http://localhost:4321 (hot reload)
npm run build # static dist/
npm run preview # serves dist/ on http://localhost:4321

Project layout

ikeanalytics-com/
├── astro.config.mjs # integrations: tailwind, sitemap, mdx
├── tailwind.config.js # Ike palette (gold / red / teal)
├── src/
│ ├── styles/globals.css # ike-card, ike-btn-*, text-gradient-*, glass
│ ├── content/blog/ # markdown articles
│ ├── components/ # Nav, Footer, Hero, ArticleCard, SocialLinks
│ ├── layouts/ # BaseLayout.astro (head, JSON-LD, RSS)
│ └── pages/ # /, /articles, /articles/[...slug], /about, /now, /404
├── public/brand/ # logos (decoupled from PSP)
└── deploy/ # nginx + cloudflared configs + deploy script

Authoring an article

Drop a markdown file into src/content/blog/:

---title: "Your title"description: "One-sentence summary that goes in OG, RSS, and the meta description."pubDate: 2026-07-15tags: ["aip", "protocols"]---
Body in markdown. Headings, lists, code blocks all work. The article URL is
auto-generated from the filename (`your-title.md``/articles/your-title/`).

Frontmatter is validated by the Zod schema in src/content/config.ts. The homepage and /articles index pick the new post up automatically on the next build.

Deploy

The site is static. dist/ ships to the Pi, nginx serves it on 127.0.0.1:8080, and cloudflared tunnels public traffic to that port. The Pi does not need a public IP - cloudflared opens an outbound TCP 443 connection to Cloudflare's edge.

./deploy/deploy.ps1 # target comes from deploy/pi-host.txt (see deploy.ps1)

That runs npm run build, scp -r dist/* to the Pi, and reloads nginx. The Pi's nginx config is in deploy/nginx-ikeanalytics.com.conf - install it at /etc/nginx/sites-available/ikeanalytics.com and symlink to sites-enabled/. The Cloudflare Tunnel config is in deploy/cloudflared-config.yml.example - see the comments in that file for the one-time setup (cloudflared tunnel login, tunnel create, tunnel route dns, service install).

Auth: SSH key only. The Pi's pi user must have your public key in ~/.ssh/authorized_keys. The deploy script defaults to $env:USERPROFILE\.ssh\id_ed25519; pass -SshKey <path> to override.

The Ike color brands

From the PSP design system, with PSP-specific shims removed:

TokenHexUse
ike-gold#D4A017Primary surface accent
ike-gold-light#E8C547Hover state
ike-gold-dark#A07810Deep accent
ike-red#C41E3ASignal - personal data boundary, accent bar
ike-teal#1A9B8AVerified / live / coordinated state
surface-dark#0D0D0DCanvas
surface-card#141414Card surface
surface-border#2A2A2AHairline borders

Component classes: ike-card, ike-card-gold/teal/red, ike-btn-gold/red/ghost, ike-label, ike-badge-gold/teal/red, text-gradient-gold, text-gradient-ike, glass, ike-accent-bar, ike-accent-bar-gold.

Fonts: Inter (sans), Syne (display), JetBrains Mono (mono). Loaded once via Google Fonts in BaseLayout.astro.

Constraints

  • No employer name anywhere. This is a public constraint inherited from the AIP launch state - see about.astro and the article copy.
  • AIP is a brand, Ike Analytics is a brand, this site is the Ike Analytics surface. The protocol has its own surface (the GitHub repo + whitepaper). Don't conflate them in copy. The footer carries an "Apache-2.0" tag near the AIP link as a reminder that the protocol is openly licensed for adoption.
  • Dark-only. No light mode. This matches PSP and the protocol aesthetic.

License

This site is the personal surface for Isaac Liem. The article text and the site code are © Isaac Liem. The AIP protocol is dual-licensed: the spec is under CC BY 4.0 and the reference implementation is under Apache License 2.0 - the most adoption-friendly strong-copyleft that's still open source by the OSI, with the explicit patent grant. See github.com/githubscum/aip-protocol. ike OS (the reference runtime that ships AIP) is under AGPL-3.0-or-later; see github.com/githubscum/psp. The protocol and the runtime are licensed differently on purpose: AIP is meant to be adopted by anyone, including closed-source products, while ike OS itself stays copyleft to keep forks of the runtime accountable.

About

ikeanalytics.com - Astro site, dark editorial system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ikeanalytics.com - personal site

A small static site for Isaac Liem at ikeanalytics.com. Built with Astro and the same Ike color brands and component vocabulary that ship in PSP. The site is authored as markdown articles served as a true static dist/, hosted on a Raspberry Pi 5 behind a Cloudflare Tunnel.

Quick start

npm install
npm run dev # dev server on http://localhost:4321 (hot reload)
npm run build # static dist/
npm run preview # serves dist/ on http://localhost:4321

Project layout

ikeanalytics-com/
├── astro.config.mjs # integrations: tailwind, sitemap, mdx
├── tailwind.config.js # Ike palette (gold / red / teal)
├── src/
│ ├── styles/globals.css # ike-card, ike-btn-*, text-gradient-*, glass
│ ├── content/blog/ # markdown articles
│ ├── components/ # Nav, Footer, Hero, ArticleCard, SocialLinks
│ ├── layouts/ # BaseLayout.astro (head, JSON-LD, RSS)
│ └── pages/ # /, /articles, /articles/[...slug], /about, /now, /404
├── public/brand/ # logos (decoupled from PSP)
└── deploy/ # nginx + cloudflared configs + deploy script

Authoring an article

Drop a markdown file into src/content/blog/:

---title: "Your title"description: "One-sentence summary that goes in OG, RSS, and the meta description."pubDate: 2026-07-15tags: ["aip", "protocols"]---
Body in markdown. Headings, lists, code blocks all work. The article URL is
auto-generated from the filename (`your-title.md``/articles/your-title/`).

Frontmatter is validated by the Zod schema in src/content/config.ts. The homepage and /articles index pick the new post up automatically on the next build.

Deploy

The site is static. dist/ ships to the Pi, nginx serves it on 127.0.0.1:8080, and cloudflared tunnels public traffic to that port. The Pi does not need a public IP - cloudflared opens an outbound TCP 443 connection to Cloudflare's edge.

./deploy/deploy.ps1 # target comes from deploy/pi-host.txt (see deploy.ps1)

That runs npm run build, scp -r dist/* to the Pi, and reloads nginx. The Pi's nginx config is in deploy/nginx-ikeanalytics.com.conf - install it at /etc/nginx/sites-available/ikeanalytics.com and symlink to sites-enabled/. The Cloudflare Tunnel config is in deploy/cloudflared-config.yml.example - see the comments in that file for the one-time setup (cloudflared tunnel login, tunnel create, tunnel route dns, service install).

Auth: SSH key only. The Pi's pi user must have your public key in ~/.ssh/authorized_keys. The deploy script defaults to $env:USERPROFILE\.ssh\id_ed25519; pass -SshKey <path> to override.

The Ike color brands

From the PSP design system, with PSP-specific shims removed:

TokenHexUse
ike-gold#D4A017Primary surface accent
ike-gold-light#E8C547Hover state
ike-gold-dark#A07810Deep accent
ike-red#C41E3ASignal - personal data boundary, accent bar
ike-teal#1A9B8AVerified / live / coordinated state
surface-dark#0D0D0DCanvas
surface-card#141414Card surface
surface-border#2A2A2AHairline borders

Component classes: ike-card, ike-card-gold/teal/red, ike-btn-gold/red/ghost, ike-label, ike-badge-gold/teal/red, text-gradient-gold, text-gradient-ike, glass, ike-accent-bar, ike-accent-bar-gold.

Fonts: Inter (sans), Syne (display), JetBrains Mono (mono). Loaded once via Google Fonts in BaseLayout.astro.

Constraints

  • No employer name anywhere. This is a public constraint inherited from the AIP launch state - see about.astro and the article copy.
  • AIP is a brand, Ike Analytics is a brand, this site is the Ike Analytics surface. The protocol has its own surface (the GitHub repo + whitepaper). Don't conflate them in copy. The footer carries an "Apache-2.0" tag near the AIP link as a reminder that the protocol is openly licensed for adoption.
  • Dark-only. No light mode. This matches PSP and the protocol aesthetic.

License

This site is the personal surface for Isaac Liem. The article text and the site code are © Isaac Liem. The AIP protocol is dual-licensed: the spec is under CC BY 4.0 and the reference implementation is under Apache License 2.0 - the most adoption-friendly strong-copyleft that's still open source by the OSI, with the explicit patent grant. See github.com/githubscum/aip-protocol. ike OS (the reference runtime that ships AIP) is under AGPL-3.0-or-later; see github.com/githubscum/psp. The protocol and the runtime are licensed differently on purpose: AIP is meant to be adopted by anyone, including closed-source products, while ike OS itself stays copyleft to keep forks of the runtime accountable.

About

ikeanalytics.com - Astro site, dark editorial system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Repository files navigation

ikeanalytics.com - personal site

A small static site for Isaac Liem at ikeanalytics.com. Built with Astro and the same Ike color brands and component vocabulary that ship in PSP. The site is authored as markdown articles served as a true static dist/, hosted on a Raspberry Pi 5 behind a Cloudflare Tunnel.

Quick start

npm install
npm run dev # dev server on http://localhost:4321 (hot reload)
npm run build # static dist/
npm run preview # serves dist/ on http://localhost:4321

Project layout

ikeanalytics-com/
├── astro.config.mjs # integrations: tailwind, sitemap, mdx
├── tailwind.config.js # Ike palette (gold / red / teal)
├── src/
│ ├── styles/globals.css # ike-card, ike-btn-*, text-gradient-*, glass
│ ├── content/blog/ # markdown articles
│ ├── components/ # Nav, Footer, Hero, ArticleCard, SocialLinks
│ ├── layouts/ # BaseLayout.astro (head, JSON-LD, RSS)
│ └── pages/ # /, /articles, /articles/[...slug], /about, /now, /404
├── public/brand/ # logos (decoupled from PSP)
└── deploy/ # nginx + cloudflared configs + deploy script

Authoring an article

Drop a markdown file into src/content/blog/:

---title: "Your title"description: "One-sentence summary that goes in OG, RSS, and the meta description."pubDate: 2026-07-15tags: ["aip", "protocols"]---
Body in markdown. Headings, lists, code blocks all work. The article URL is
auto-generated from the filename (`your-title.md``/articles/your-title/`).

Frontmatter is validated by the Zod schema in src/content/config.ts. The homepage and /articles index pick the new post up automatically on the next build.

Deploy

The site is static. dist/ ships to the Pi, nginx serves it on 127.0.0.1:8080, and cloudflared tunnels public traffic to that port. The Pi does not need a public IP - cloudflared opens an outbound TCP 443 connection to Cloudflare's edge.

./deploy/deploy.ps1 # target comes from deploy/pi-host.txt (see deploy.ps1)

That runs npm run build, scp -r dist/* to the Pi, and reloads nginx. The Pi's nginx config is in deploy/nginx-ikeanalytics.com.conf - install it at /etc/nginx/sites-available/ikeanalytics.com and symlink to sites-enabled/. The Cloudflare Tunnel config is in deploy/cloudflared-config.yml.example - see the comments in that file for the one-time setup (cloudflared tunnel login, tunnel create, tunnel route dns, service install).

Auth: SSH key only. The Pi's pi user must have your public key in ~/.ssh/authorized_keys. The deploy script defaults to $env:USERPROFILE\.ssh\id_ed25519; pass -SshKey <path> to override.

The Ike color brands

From the PSP design system, with PSP-specific shims removed:

TokenHexUse
ike-gold#D4A017Primary surface accent
ike-gold-light#E8C547Hover state
ike-gold-dark#A07810Deep accent
ike-red#C41E3ASignal - personal data boundary, accent bar
ike-teal#1A9B8AVerified / live / coordinated state
surface-dark#0D0D0DCanvas
surface-card#141414Card surface
surface-border#2A2A2AHairline borders

Component classes: ike-card, ike-card-gold/teal/red, ike-btn-gold/red/ghost, ike-label, ike-badge-gold/teal/red, text-gradient-gold, text-gradient-ike, glass, ike-accent-bar, ike-accent-bar-gold.

Fonts: Inter (sans), Syne (display), JetBrains Mono (mono). Loaded once via Google Fonts in BaseLayout.astro.

Constraints

  • No employer name anywhere. This is a public constraint inherited from the AIP launch state - see about.astro and the article copy.
  • AIP is a brand, Ike Analytics is a brand, this site is the Ike Analytics surface. The protocol has its own surface (the GitHub repo + whitepaper). Don't conflate them in copy. The footer carries an "Apache-2.0" tag near the AIP link as a reminder that the protocol is openly licensed for adoption.
  • Dark-only. No light mode. This matches PSP and the protocol aesthetic.

License

This site is the personal surface for Isaac Liem. The article text and the site code are © Isaac Liem. The AIP protocol is dual-licensed: the spec is under CC BY 4.0 and the reference implementation is under Apache License 2.0 - the most adoption-friendly strong-copyleft that's still open source by the OSI, with the explicit patent grant. See github.com/githubscum/aip-protocol. ike OS (the reference runtime that ships AIP) is under AGPL-3.0-or-later; see github.com/githubscum/psp. The protocol and the runtime are licensed differently on purpose: AIP is meant to be adopted by anyone, including closed-source products, while ike OS itself stays copyleft to keep forks of the runtime accountable.

About

ikeanalytics.com - Astro site, dark editorial system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Repository files navigation

ikeanalytics.com - personal site

A small static site for Isaac Liem at ikeanalytics.com. Built with Astro and the same Ike color brands and component vocabulary that ship in PSP. The site is authored as markdown articles served as a true static dist/, hosted on a Raspberry Pi 5 behind a Cloudflare Tunnel.

Quick start

npm install
npm run dev # dev server on http://localhost:4321 (hot reload)
npm run build # static dist/
npm run preview # serves dist/ on http://localhost:4321

Project layout

ikeanalytics-com/
├── astro.config.mjs # integrations: tailwind, sitemap, mdx
├── tailwind.config.js # Ike palette (gold / red / teal)
├── src/
│ ├── styles/globals.css # ike-card, ike-btn-*, text-gradient-*, glass
│ ├── content/blog/ # markdown articles
│ ├── components/ # Nav, Footer, Hero, ArticleCard, SocialLinks
│ ├── layouts/ # BaseLayout.astro (head, JSON-LD, RSS)
│ └── pages/ # /, /articles, /articles/[...slug], /about, /now, /404
├── public/brand/ # logos (decoupled from PSP)
└── deploy/ # nginx + cloudflared configs + deploy script

Authoring an article

Drop a markdown file into src/content/blog/:

---title: "Your title"description: "One-sentence summary that goes in OG, RSS, and the meta description."pubDate: 2026-07-15tags: ["aip", "protocols"]---
Body in markdown. Headings, lists, code blocks all work. The article URL is
auto-generated from the filename (`your-title.md``/articles/your-title/`).

Frontmatter is validated by the Zod schema in src/content/config.ts. The homepage and /articles index pick the new post up automatically on the next build.

Deploy

The site is static. dist/ ships to the Pi, nginx serves it on 127.0.0.1:8080, and cloudflared tunnels public traffic to that port. The Pi does not need a public IP - cloudflared opens an outbound TCP 443 connection to Cloudflare's edge.

./deploy/deploy.ps1 # target comes from deploy/pi-host.txt (see deploy.ps1)

That runs npm run build, scp -r dist/* to the Pi, and reloads nginx. The Pi's nginx config is in deploy/nginx-ikeanalytics.com.conf - install it at /etc/nginx/sites-available/ikeanalytics.com and symlink to sites-enabled/. The Cloudflare Tunnel config is in deploy/cloudflared-config.yml.example - see the comments in that file for the one-time setup (cloudflared tunnel login, tunnel create, tunnel route dns, service install).

Auth: SSH key only. The Pi's pi user must have your public key in ~/.ssh/authorized_keys. The deploy script defaults to $env:USERPROFILE\.ssh\id_ed25519; pass -SshKey <path> to override.

The Ike color brands

From the PSP design system, with PSP-specific shims removed:

TokenHexUse
ike-gold#D4A017Primary surface accent
ike-gold-light#E8C547Hover state
ike-gold-dark#A07810Deep accent
ike-red#C41E3ASignal - personal data boundary, accent bar
ike-teal#1A9B8AVerified / live / coordinated state
surface-dark#0D0D0DCanvas
surface-card#141414Card surface
surface-border#2A2A2AHairline borders

Component classes: ike-card, ike-card-gold/teal/red, ike-btn-gold/red/ghost, ike-label, ike-badge-gold/teal/red, text-gradient-gold, text-gradient-ike, glass, ike-accent-bar, ike-accent-bar-gold.

Fonts: Inter (sans), Syne (display), JetBrains Mono (mono). Loaded once via Google Fonts in BaseLayout.astro.

Constraints

  • No employer name anywhere. This is a public constraint inherited from the AIP launch state - see about.astro and the article copy.
  • AIP is a brand, Ike Analytics is a brand, this site is the Ike Analytics surface. The protocol has its own surface (the GitHub repo + whitepaper). Don't conflate them in copy. The footer carries an "Apache-2.0" tag near the AIP link as a reminder that the protocol is openly licensed for adoption.
  • Dark-only. No light mode. This matches PSP and the protocol aesthetic.

License

This site is the personal surface for Isaac Liem. The article text and the site code are © Isaac Liem. The AIP protocol is dual-licensed: the spec is under CC BY 4.0 and the reference implementation is under Apache License 2.0 - the most adoption-friendly strong-copyleft that's still open source by the OSI, with the explicit patent grant. See github.com/githubscum/aip-protocol. ike OS (the reference runtime that ships AIP) is under AGPL-3.0-or-later; see github.com/githubscum/psp. The protocol and the runtime are licensed differently on purpose: AIP is meant to be adopted by anyone, including closed-source products, while ike OS itself stays copyleft to keep forks of the runtime accountable.

About

ikeanalytics.com - Astro site, dark editorial system

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages