diff --git a/.github/scripts/generate-stats.js b/.github/scripts/generate-stats.js index 9f58cd8..92753ac 100644 --- a/.github/scripts/generate-stats.js +++ b/.github/scripts/generate-stats.js @@ -9,6 +9,9 @@ const USERNAME = 'Codestz'; const PURPLE = '#7c3aed'; const TOKEN = process.env.GITHUB_TOKEN; +// Featured repos rendered as standalone cards (stars/forks auto-refreshed) +const FEATURED_REPOS = ['claude-hindsight']; + if (!TOKEN) { console.error('GITHUB_TOKEN is required'); process.exit(1); @@ -69,6 +72,19 @@ async function fetchStats() { return data.user; } +async function fetchRepo(name) { + const { data } = await githubAPI(`{ + repository(owner: "${USERNAME}", name: "${name}") { + name + description + stargazerCount + forkCount + primaryLanguage { name color } + } + }`); + return data.repository; +} + function calculateStreak(weeks) { const days = weeks .flatMap((w) => w.contributionDays) @@ -340,6 +356,73 @@ function generateContributionGraphSVG(weeks, theme) { `; } +function escapeXml(str) { + return String(str || '') + .replace(/&/g, '&') + .replace(//g, '>'); +} + +function wrapText(text, maxChars, maxLines) { + const words = String(text || '') + .split(/\s+/) + .filter(Boolean); + const all = []; + let line = ''; + for (const word of words) { + const candidate = line ? `${line} ${word}` : word; + if (candidate.length > maxChars && line) { + all.push(line); + line = word; + } else { + line = candidate; + } + } + if (line) all.push(line); + if (all.length <= maxLines) return all; + + const kept = all.slice(0, maxLines); + const last = kept[maxLines - 1]; + kept[maxLines - 1] = (last.length > maxChars - 1 ? last.slice(0, maxChars - 1) : last) + '…'; + return kept; +} + +function generateRepoCardSVG(repo, theme) { + const isDark = theme === 'dark'; + const textColor = isDark ? '#c9d1d9' : '#333333'; + const subColor = isDark ? '#888888' : '#666666'; + const lang = repo.primaryLanguage; + const descLines = wrapText(repo.description, 52, 2); + + const descSvg = descLines + .map( + (l, i) => + `${escapeXml(l)}` + ) + .join('\n '); + + const footerY = 66 + descLines.length * 20 + 18; + + const langSvg = lang + ? ` + ${escapeXml(lang.name)}` + : ''; + + const height = footerY + 20; + + return ` + + + + + ${escapeXml(repo.name)} + ${descSvg} + ${langSvg} + ★ ${repo.stargazerCount.toLocaleString()} + ⑂ ${repo.forkCount.toLocaleString()} +`; +} + async function main() { console.log('Fetching GitHub stats...'); const stats = await fetchStats(); @@ -374,6 +457,25 @@ async function main() { console.log(`Generated ${theme} theme SVGs`); } + for (const name of FEATURED_REPOS) { + try { + const repo = await fetchRepo(name); + if (!repo) { + console.log(`Repo ${name} not found, skipping card`); + continue; + } + for (const theme of ['dark', 'light']) { + fs.writeFileSync( + path.join(outDir, `repo-${name}-${theme}.svg`), + generateRepoCardSVG(repo, theme) + ); + } + console.log(`Generated repo card for ${name}`); + } catch (err) { + console.log(`Failed to generate card for ${name}: ${err.message}`); + } + } + console.log('Done! SVGs written to public/stats/'); } diff --git a/.github/workflows/update-readme.yml b/.github/workflows/update-readme.yml index 6796ce3..80b499a 100644 --- a/.github/workflows/update-readme.yml +++ b/.github/workflows/update-readme.yml @@ -40,17 +40,32 @@ jobs: try { const rss = await fetchRSS('https://codestz.dev/feed'); - const items = [...rss.matchAll(/[\s\S]*?(.*?)<\/title>[\s\S]*?<link>(.*?)<\/link>[\s\S]*?<\/item>/g)]; + const items = [...rss.matchAll(/<item>([\s\S]*?)<\/item>/g)]; if (items.length === 0) { console.log('No items found in RSS feed, skipping update'); return; } - const posts = items.slice(0, 7).map(match => { - const title = match[1].replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'"); - const link = match[2]; - return `- [${title}](${link})`; + const decode = (s) => s.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, "'"); + const MONTHS = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; + + const posts = items.slice(0, 7).map(([, block]) => { + const grab = (tag) => (block.match(new RegExp(`<${tag}>([\\s\\S]*?)<\\/${tag}>`)) || [])[1] || ''; + const title = decode(grab('title').trim()); + const link = grab('link').trim(); + const pubDate = grab('pubDate').trim(); + const readingTime = decode(grab('blog:readingTime').trim()); + + const meta = []; + if (pubDate) { + const d = new Date(pubDate); + if (!isNaN(d)) meta.push(`${MONTHS[d.getUTCMonth()]} ${d.getUTCFullYear()}`); + } + if (readingTime) meta.push(readingTime.replace(/ read$/, '')); + + const suffix = meta.length ? ` — ${meta.join(' · ')}` : ''; + return `- [${title}](${link})${suffix}`; }).join('\n'); const readme = fs.readFileSync('README.md', 'utf8'); diff --git a/README.md b/README.md index fd275c1..42100eb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ <div align="center"> -[![Typing SVG](https://readme-typing-svg.demolab.com?font=JetBrains+Mono&weight=700&size=32&duration=3000&pause=1000&color=7C3AED¢er=true&vCenter=true&random=false&width=700&height=70&lines=Hey%2C+I'm+Esteban+Estrada;Software+Engineer+II+%40+Recurly;Building+tools+for+AI+agents;Rust+%7C+TypeScript+%7C+Go)](https://codestz.dev) +[![Typing SVG](https://readme-typing-svg.demolab.com?font=JetBrains+Mono&weight=700&size=32&duration=3000&pause=1000&color=7C3AED¢er=true&vCenter=true&random=false&width=700&height=70&lines=Hey%2C+I'm+Esteban+Estrada;Senior+Software+Engineer+%40+Recurly;Building+tools+for+AI+agents;Rust+%7C+TypeScript+%7C+Go)](https://codestz.dev) I build developer tools that make AI agents smarter. <br/>Rust, TypeScript, Go — CLIs, MCP servers, LSP integrations. @@ -86,6 +86,18 @@ I build developer tools that make AI agents smarter. --- +### Featured Project + +<a href="https://github.com/Codestz/claude-hindsight"> +<picture> + <source media="(prefers-color-scheme: dark)" srcset="./public/stats/repo-claude-hindsight-dark.svg"/> + <source media="(prefers-color-scheme: light)" srcset="./public/stats/repo-claude-hindsight-light.svg"/> + <img src="./public/stats/repo-claude-hindsight-dark.svg" alt="claude-hindsight"/> +</picture> +</a> + +--- + ### Projects [**krait**](https://github.com/Codestz/krait) -- Code intelligence CLI for AI agents. LSP-backed symbol search, semantic editing, and diagnostics in a single Rust binary. `rust` @@ -107,6 +119,7 @@ I build developer tools that make AI agents smarter. > I write about AI-driven development, MCP integrations, and developer tooling at **[codestz.dev](https://codestz.dev)** <!-- BLOG-POST-LIST:START --> + - [Stop Vibe Coding. Start Vibe Engineering.](https://codestz.dev/experiments/stop-vibe-coding-start-vibe-engineering) - [Stop Loading 100K Tokens Just to Call a Tool: Why I Built MCPX](https://codestz.dev/experiments/mcpx-mcp-gateway) - [The AI Convergence: Why Every Coding Tool Lands on the Same Two Defaults](https://codestz.dev/experiments/why-ai-defaults-to-typescript) diff --git a/public/robots.txt b/public/robots.txt deleted file mode 100644 index 92454d4..0000000 --- a/public/robots.txt +++ /dev/null @@ -1,10 +0,0 @@ -# https://www.robotstxt.org/robotstxt.html -User-agent: * -Allow: / - -# Sitemap -Sitemap: https://estebanestrada.dev/sitemap.xml - -# Disallow private paths (if any) -# Disallow: /api/ -# Disallow: /admin/ diff --git a/public/stats/contributions-dark.svg b/public/stats/contributions-dark.svg index 5c07101..ff9a797 100644 --- a/public/stats/contributions-dark.svg +++ b/public/stats/contributions-dark.svg @@ -1,6 +1,6 @@ <svg xmlns="http://www.w3.org/2000/svg" width="726" height="161" viewBox="0 0 726 161"> <text x="30" y="20" fill="#7c3aed" font-size="16" font-weight="bold" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Contribution Graph</text> - <text x="30" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Jun</text><text x="82" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Jul</text><text x="134" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Aug</text><text x="199" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Sep</text><text x="251" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Oct</text><text x="303" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Nov</text><text x="368" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Dec</text><text x="420" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Jan</text><text x="472" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Feb</text><text x="524" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Mar</text><text x="589" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Apr</text><text x="641" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">May</text> + <text x="30" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Jun</text><text x="82" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Jul</text><text x="134" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Aug</text><text x="199" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Sep</text><text x="251" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Oct</text><text x="303" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Nov</text><text x="368" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Dec</text><text x="420" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Jan</text><text x="485" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Feb</text><text x="537" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Mar</text><text x="589" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Apr</text><text x="641" y="32" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">May</text> <text x="0" y="62" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Mon</text><text x="0" y="88" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Wed</text><text x="0" y="114" fill="#888888" font-size="10" font-family="'Segoe UI', Ubuntu, 'Helvetica Neue', sans-serif">Fri</text> - <rect x="30" y="40" width="11" height="11" fill="#161b22" rx="2"><title>2025-06-08: 0 contributions2025-06-09: 0 contributions2025-06-10: 0 contributions2025-06-11: 0 contributions2025-06-12: 1 contributions2025-06-13: 0 contributions2025-06-14: 0 contributions2025-06-15: 2 contributions2025-06-16: 8 contributions2025-06-17: 1 contributions2025-06-18: 15 contributions2025-06-19: 6 contributions2025-06-20: 6 contributions2025-06-21: 0 contributions2025-06-22: 0 contributions2025-06-23: 0 contributions2025-06-24: 0 contributions2025-06-25: 0 contributions2025-06-26: 0 contributions2025-06-27: 0 contributions2025-06-28: 0 contributions2025-06-29: 0 contributions2025-06-30: 0 contributions2025-07-01: 0 contributions2025-07-02: 0 contributions2025-07-03: 0 contributions2025-07-04: 0 contributions2025-07-05: 0 contributions2025-07-06: 0 contributions2025-07-07: 0 contributions2025-07-08: 0 contributions2025-07-09: 0 contributions2025-07-10: 0 contributions2025-07-11: 0 contributions2025-07-12: 0 contributions2025-07-13: 0 contributions2025-07-14: 0 contributions2025-07-15: 0 contributions2025-07-16: 0 contributions2025-07-17: 0 contributions2025-07-18: 0 contributions2025-07-19: 0 contributions2025-07-20: 0 contributions2025-07-21: 0 contributions2025-07-22: 0 contributions2025-07-23: 0 contributions2025-07-24: 0 contributions2025-07-25: 0 contributions2025-07-26: 0 contributions2025-07-27: 0 contributions2025-07-28: 0 contributions2025-07-29: 0 contributions2025-07-30: 0 contributions2025-07-31: 0 contributions2025-08-01: 0 contributions2025-08-02: 0 contributions2025-08-03: 0 contributions2025-08-04: 0 contributions2025-08-05: 0 contributions2025-08-06: 0 contributions2025-08-07: 0 contributions2025-08-08: 0 contributions2025-08-09: 0 contributions2025-08-10: 0 contributions2025-08-11: 0 contributions2025-08-12: 0 contributions2025-08-13: 0 contributions2025-08-14: 0 contributions2025-08-15: 0 contributions2025-08-16: 0 contributions2025-08-17: 0 contributions2025-08-18: 0 contributions2025-08-19: 0 contributions2025-08-20: 0 contributions2025-08-21: 0 contributions2025-08-22: 0 contributions2025-08-23: 0 contributions2025-08-24: 0 contributions2025-08-25: 0 contributions2025-08-26: 0 contributions2025-08-27: 0 contributions2025-08-28: 0 contributions2025-08-29: 0 contributions2025-08-30: 0 contributions2025-08-31: 0 contributions2025-09-01: 0 contributions2025-09-02: 0 contributions2025-09-03: 0 contributions2025-09-04: 0 contributions2025-09-05: 0 contributions2025-09-06: 0 contributions2025-09-07: 0 contributions2025-09-08: 0 contributions2025-09-09: 0 contributions2025-09-10: 0 contributions2025-09-11: 0 contributions2025-09-12: 0 contributions2025-09-13: 0 contributions2025-09-14: 0 contributions2025-09-15: 0 contributions2025-09-16: 0 contributions2025-09-17: 0 contributions2025-09-18: 0 contributions2025-09-19: 0 contributions2025-09-20: 0 contributions2025-09-21: 0 contributions2025-09-22: 0 contributions2025-09-23: 0 contributions2025-09-24: 0 contributions2025-09-25: 0 contributions2025-09-26: 0 contributions2025-09-27: 0 contributions2025-09-28: 0 contributions2025-09-29: 0 contributions2025-09-30: 0 contributions2025-10-01: 0 contributions2025-10-02: 0 contributions2025-10-03: 0 contributions2025-10-04: 0 contributions2025-10-05: 0 contributions2025-10-06: 0 contributions2025-10-07: 0 contributions2025-10-08: 0 contributions2025-10-09: 0 contributions2025-10-10: 0 contributions2025-10-11: 0 contributions2025-10-12: 0 contributions2025-10-13: 0 contributions2025-10-14: 0 contributions2025-10-15: 0 contributions2025-10-16: 0 contributions2025-10-17: 0 contributions2025-10-18: 0 contributions2025-10-19: 0 contributions2025-10-20: 0 contributions2025-10-21: 0 contributions2025-10-22: 0 contributions2025-10-23: 0 contributions2025-10-24: 0 contributions2025-10-25: 0 contributions2025-10-26: 0 contributions2025-10-27: 0 contributions2025-10-28: 0 contributions2025-10-29: 0 contributions2025-10-30: 0 contributions2025-10-31: 0 contributions2025-11-01: 0 contributions2025-11-02: 0 contributions2025-11-03: 0 contributions2025-11-04: 0 contributions2025-11-05: 0 contributions2025-11-06: 0 contributions2025-11-07: 0 contributions2025-11-08: 0 contributions2025-11-09: 0 contributions2025-11-10: 0 contributions2025-11-11: 0 contributions2025-11-12: 0 contributions2025-11-13: 0 contributions2025-11-14: 0 contributions2025-11-15: 0 contributions2025-11-16: 0 contributions2025-11-17: 0 contributions2025-11-18: 0 contributions2025-11-19: 0 contributions2025-11-20: 0 contributions2025-11-21: 0 contributions2025-11-22: 0 contributions2025-11-23: 0 contributions2025-11-24: 0 contributions2025-11-25: 0 contributions2025-11-26: 0 contributions2025-11-27: 0 contributions2025-11-28: 0 contributions2025-11-29: 0 contributions2025-11-30: 0 contributions2025-12-01: 0 contributions2025-12-02: 0 contributions2025-12-03: 0 contributions2025-12-04: 0 contributions2025-12-05: 0 contributions2025-12-06: 0 contributions2025-12-07: 0 contributions2025-12-08: 0 contributions2025-12-09: 0 contributions2025-12-10: 0 contributions2025-12-11: 0 contributions2025-12-12: 0 contributions2025-12-13: 0 contributions2025-12-14: 0 contributions2025-12-15: 0 contributions2025-12-16: 0 contributions2025-12-17: 0 contributions2025-12-18: 0 contributions2025-12-19: 0 contributions2025-12-20: 0 contributions2025-12-21: 0 contributions2025-12-22: 0 contributions2025-12-23: 0 contributions2025-12-24: 0 contributions2025-12-25: 0 contributions2025-12-26: 0 contributions2025-12-27: 0 contributions2025-12-28: 0 contributions2025-12-29: 0 contributions2025-12-30: 0 contributions2025-12-31: 0 contributions2026-01-01: 0 contributions2026-01-02: 0 contributions2026-01-03: 0 contributions2026-01-04: 0 contributions2026-01-05: 0 contributions2026-01-06: 0 contributions2026-01-07: 0 contributions2026-01-08: 0 contributions2026-01-09: 0 contributions2026-01-10: 0 contributions2026-01-11: 0 contributions2026-01-12: 0 contributions2026-01-13: 0 contributions2026-01-14: 0 contributions2026-01-15: 0 contributions2026-01-16: 0 contributions2026-01-17: 0 contributions2026-01-18: 0 contributions2026-01-19: 0 contributions2026-01-20: 0 contributions2026-01-21: 0 contributions2026-01-22: 0 contributions2026-01-23: 0 contributions2026-01-24: 0 contributions2026-01-25: 0 contributions2026-01-26: 0 contributions2026-01-27: 0 contributions2026-01-28: 0 contributions2026-01-29: 0 contributions2026-01-30: 0 contributions2026-01-31: 0 contributions2026-02-01: 0 contributions2026-02-02: 0 contributions2026-02-03: 0 contributions2026-02-04: 0 contributions2026-02-05: 0 contributions2026-02-06: 0 contributions2026-02-07: 0 contributions2026-02-08: 14 contributions2026-02-09: 8 contributions2026-02-10: 1 contributions2026-02-11: 0 contributions2026-02-12: 4 contributions2026-02-13: 0 contributions2026-02-14: 0 contributions2026-02-15: 20 contributions2026-02-16: 34 contributions2026-02-17: 0 contributions2026-02-18: 0 contributions2026-02-19: 18 contributions2026-02-20: 55 contributions2026-02-21: 4 contributions2026-02-22: 0 contributions2026-02-23: 6 contributions2026-02-24: 0 contributions2026-02-25: 1 contributions2026-02-26: 0 contributions2026-02-27: 0 contributions2026-02-28: 17 contributions2026-03-01: 7 contributions2026-03-02: 11 contributions2026-03-03: 0 contributions2026-03-04: 0 contributions2026-03-05: 0 contributions2026-03-06: 3 contributions2026-03-07: 0 contributions2026-03-08: 0 contributions2026-03-09: 24 contributions2026-03-10: 0 contributions2026-03-11: 0 contributions2026-03-12: 0 contributions2026-03-13: 15 contributions2026-03-14: 45 contributions2026-03-15: 9 contributions2026-03-16: 0 contributions2026-03-17: 5 contributions2026-03-18: 2 contributions2026-03-19: 0 contributions2026-03-20: 6 contributions2026-03-21: 0 contributions2026-03-22: 0 contributions2026-03-23: 3 contributions2026-03-24: 0 contributions2026-03-25: 0 contributions2026-03-26: 0 contributions2026-03-27: 0 contributions2026-03-28: 6 contributions2026-03-29: 5 contributions2026-03-30: 9 contributions2026-03-31: 0 contributions2026-04-01: 0 contributions2026-04-02: 0 contributions2026-04-03: 0 contributions2026-04-04: 0 contributions2026-04-05: 0 contributions2026-04-06: 0 contributions2026-04-07: 0 contributions2026-04-08: 0 contributions2026-04-09: 0 contributions2026-04-10: 0 contributions2026-04-11: 0 contributions2026-04-12: 0 contributions2026-04-13: 0 contributions2026-04-14: 0 contributions2026-04-15: 0 contributions2026-04-16: 0 contributions2026-04-17: 0 contributions2026-04-18: 0 contributions2026-04-19: 0 contributions2026-04-20: 0 contributions2026-04-21: 0 contributions2026-04-22: 0 contributions2026-04-23: 0 contributions2026-04-24: 0 contributions2026-04-25: 0 contributions2026-04-26: 0 contributions2026-04-27: 0 contributions2026-04-28: 0 contributions2026-04-29: 0 contributions2026-04-30: 0 contributions2026-05-01: 0 contributions2026-05-02: 0 contributions2026-05-03: 8 contributions2026-05-04: 0 contributions2026-05-05: 0 contributions2026-05-06: 0 contributions2026-05-07: 0 contributions2026-05-08: 0 contributions2026-05-09: 18 contributions2026-05-10: 44 contributions2026-05-11: 17 contributions2026-05-12: 0 contributions2026-05-13: 0 contributions2026-05-14: 0 contributions2026-05-15: 0 contributions2026-05-16: 0 contributions2026-05-17: 0 contributions2026-05-18: 0 contributions2026-05-19: 0 contributions2026-05-20: 0 contributions2026-05-21: 0 contributions2026-05-22: 0 contributions2026-05-23: 0 contributions2026-05-24: 0 contributions2026-05-25: 0 contributions2026-05-26: 0 contributions2026-05-27: 0 contributions2026-05-28: 0 contributions2026-05-29: 0 contributions2026-05-30: 0 contributions2026-05-31: 0 contributions2026-06-01: 0 contributions2026-06-02: 0 contributions2026-06-03: 3 contributions + 2025-06-08: 0 contributions2025-06-09: 0 contributions2025-06-10: 0 contributions2025-06-11: 0 contributions2025-06-12: 1 contributions2025-06-13: 0 contributions2025-06-14: 0 contributions2025-06-15: 3 contributions2025-06-16: 7 contributions2025-06-17: 1 contributions2025-06-18: 15 contributions2025-06-19: 7 contributions2025-06-20: 5 contributions2025-06-21: 0 contributions2025-06-22: 0 contributions2025-06-23: 0 contributions2025-06-24: 0 contributions2025-06-25: 0 contributions2025-06-26: 0 contributions2025-06-27: 0 contributions2025-06-28: 0 contributions2025-06-29: 0 contributions2025-06-30: 0 contributions2025-07-01: 0 contributions2025-07-02: 0 contributions2025-07-03: 0 contributions2025-07-04: 0 contributions2025-07-05: 0 contributions2025-07-06: 0 contributions2025-07-07: 0 contributions2025-07-08: 0 contributions2025-07-09: 0 contributions2025-07-10: 0 contributions2025-07-11: 0 contributions2025-07-12: 0 contributions2025-07-13: 0 contributions2025-07-14: 0 contributions2025-07-15: 0 contributions2025-07-16: 0 contributions2025-07-17: 0 contributions2025-07-18: 0 contributions2025-07-19: 0 contributions2025-07-20: 0 contributions2025-07-21: 0 contributions2025-07-22: 0 contributions2025-07-23: 0 contributions2025-07-24: 0 contributions2025-07-25: 0 contributions2025-07-26: 0 contributions2025-07-27: 0 contributions2025-07-28: 0 contributions2025-07-29: 0 contributions2025-07-30: 0 contributions2025-07-31: 0 contributions2025-08-01: 0 contributions2025-08-02: 0 contributions2025-08-03: 0 contributions2025-08-04: 0 contributions2025-08-05: 0 contributions2025-08-06: 0 contributions2025-08-07: 0 contributions2025-08-08: 0 contributions2025-08-09: 0 contributions2025-08-10: 0 contributions2025-08-11: 0 contributions2025-08-12: 0 contributions2025-08-13: 0 contributions2025-08-14: 0 contributions2025-08-15: 0 contributions2025-08-16: 0 contributions2025-08-17: 0 contributions2025-08-18: 0 contributions2025-08-19: 0 contributions2025-08-20: 0 contributions2025-08-21: 0 contributions2025-08-22: 0 contributions2025-08-23: 0 contributions2025-08-24: 0 contributions2025-08-25: 0 contributions2025-08-26: 0 contributions2025-08-27: 0 contributions2025-08-28: 0 contributions2025-08-29: 0 contributions2025-08-30: 0 contributions2025-08-31: 0 contributions2025-09-01: 0 contributions2025-09-02: 0 contributions2025-09-03: 0 contributions2025-09-04: 0 contributions2025-09-05: 0 contributions2025-09-06: 0 contributions2025-09-07: 0 contributions2025-09-08: 0 contributions2025-09-09: 0 contributions2025-09-10: 0 contributions2025-09-11: 0 contributions2025-09-12: 0 contributions2025-09-13: 0 contributions2025-09-14: 0 contributions2025-09-15: 0 contributions2025-09-16: 0 contributions2025-09-17: 0 contributions2025-09-18: 0 contributions2025-09-19: 0 contributions2025-09-20: 0 contributions2025-09-21: 0 contributions2025-09-22: 0 contributions2025-09-23: 0 contributions2025-09-24: 0 contributions2025-09-25: 0 contributions2025-09-26: 0 contributions2025-09-27: 0 contributions2025-09-28: 0 contributions2025-09-29: 0 contributions2025-09-30: 0 contributions2025-10-01: 0 contributions2025-10-02: 0 contributions2025-10-03: 0 contributions2025-10-04: 0 contributions2025-10-05: 0 contributions2025-10-06: 0 contributions2025-10-07: 0 contributions2025-10-08: 0 contributions2025-10-09: 0 contributions2025-10-10: 0 contributions2025-10-11: 0 contributions2025-10-12: 0 contributions2025-10-13: 0 contributions2025-10-14: 0 contributions2025-10-15: 0 contributions2025-10-16: 0 contributions2025-10-17: 0 contributions2025-10-18: 0 contributions2025-10-19: 0 contributions2025-10-20: 0 contributions2025-10-21: 0 contributions2025-10-22: 0 contributions2025-10-23: 0 contributions2025-10-24: 0 contributions2025-10-25: 0 contributions2025-10-26: 0 contributions2025-10-27: 0 contributions2025-10-28: 0 contributions2025-10-29: 0 contributions2025-10-30: 0 contributions2025-10-31: 0 contributions2025-11-01: 0 contributions2025-11-02: 0 contributions2025-11-03: 0 contributions2025-11-04: 0 contributions2025-11-05: 0 contributions2025-11-06: 0 contributions2025-11-07: 0 contributions2025-11-08: 0 contributions2025-11-09: 0 contributions2025-11-10: 0 contributions2025-11-11: 0 contributions2025-11-12: 0 contributions2025-11-13: 0 contributions2025-11-14: 0 contributions2025-11-15: 0 contributions2025-11-16: 0 contributions2025-11-17: 0 contributions2025-11-18: 0 contributions2025-11-19: 0 contributions2025-11-20: 0 contributions2025-11-21: 0 contributions2025-11-22: 0 contributions2025-11-23: 0 contributions2025-11-24: 0 contributions2025-11-25: 0 contributions2025-11-26: 0 contributions2025-11-27: 0 contributions2025-11-28: 0 contributions2025-11-29: 0 contributions2025-11-30: 0 contributions2025-12-01: 0 contributions2025-12-02: 0 contributions2025-12-03: 0 contributions2025-12-04: 0 contributions2025-12-05: 0 contributions2025-12-06: 0 contributions2025-12-07: 0 contributions2025-12-08: 0 contributions2025-12-09: 0 contributions2025-12-10: 0 contributions2025-12-11: 0 contributions2025-12-12: 0 contributions2025-12-13: 0 contributions2025-12-14: 0 contributions2025-12-15: 0 contributions2025-12-16: 0 contributions2025-12-17: 0 contributions2025-12-18: 0 contributions2025-12-19: 0 contributions2025-12-20: 0 contributions2025-12-21: 0 contributions2025-12-22: 0 contributions2025-12-23: 0 contributions2025-12-24: 0 contributions2025-12-25: 0 contributions2025-12-26: 0 contributions2025-12-27: 0 contributions2025-12-28: 0 contributions2025-12-29: 0 contributions2025-12-30: 0 contributions2025-12-31: 0 contributions2026-01-01: 0 contributions2026-01-02: 0 contributions2026-01-03: 0 contributions2026-01-04: 0 contributions2026-01-05: 0 contributions2026-01-06: 0 contributions2026-01-07: 0 contributions2026-01-08: 0 contributions2026-01-09: 0 contributions2026-01-10: 0 contributions2026-01-11: 0 contributions2026-01-12: 0 contributions2026-01-13: 0 contributions2026-01-14: 0 contributions2026-01-15: 0 contributions2026-01-16: 0 contributions2026-01-17: 0 contributions2026-01-18: 0 contributions2026-01-19: 0 contributions2026-01-20: 0 contributions2026-01-21: 0 contributions2026-01-22: 0 contributions2026-01-23: 0 contributions2026-01-24: 0 contributions2026-01-25: 0 contributions2026-01-26: 0 contributions2026-01-27: 0 contributions2026-01-28: 0 contributions2026-01-29: 0 contributions2026-01-30: 0 contributions2026-01-31: 0 contributions2026-02-01: 0 contributions2026-02-02: 0 contributions2026-02-03: 0 contributions2026-02-04: 0 contributions2026-02-05: 0 contributions2026-02-06: 0 contributions2026-02-07: 0 contributions2026-02-08: 15 contributions2026-02-09: 7 contributions2026-02-10: 1 contributions2026-02-11: 0 contributions2026-02-12: 4 contributions2026-02-13: 0 contributions2026-02-14: 0 contributions2026-02-15: 21 contributions2026-02-16: 33 contributions2026-02-17: 0 contributions2026-02-18: 0 contributions2026-02-19: 18 contributions2026-02-20: 55 contributions2026-02-21: 4 contributions2026-02-22: 0 contributions2026-02-23: 6 contributions2026-02-24: 0 contributions2026-02-25: 1 contributions2026-02-26: 0 contributions2026-02-27: 0 contributions2026-02-28: 17 contributions2026-03-01: 7 contributions2026-03-02: 11 contributions2026-03-03: 0 contributions2026-03-04: 0 contributions2026-03-05: 0 contributions2026-03-06: 3 contributions2026-03-07: 0 contributions2026-03-08: 0 contributions2026-03-09: 24 contributions2026-03-10: 0 contributions2026-03-11: 0 contributions2026-03-12: 0 contributions2026-03-13: 15 contributions2026-03-14: 45 contributions2026-03-15: 9 contributions2026-03-16: 0 contributions2026-03-17: 5 contributions2026-03-18: 2 contributions2026-03-19: 0 contributions2026-03-20: 6 contributions2026-03-21: 0 contributions2026-03-22: 0 contributions2026-03-23: 3 contributions2026-03-24: 0 contributions2026-03-25: 0 contributions2026-03-26: 0 contributions2026-03-27: 0 contributions2026-03-28: 6 contributions2026-03-29: 5 contributions2026-03-30: 9 contributions2026-03-31: 0 contributions2026-04-01: 0 contributions2026-04-02: 0 contributions2026-04-03: 0 contributions2026-04-04: 0 contributions2026-04-05: 0 contributions2026-04-06: 0 contributions2026-04-07: 0 contributions2026-04-08: 0 contributions2026-04-09: 0 contributions2026-04-10: 0 contributions2026-04-11: 0 contributions2026-04-12: 0 contributions2026-04-13: 0 contributions2026-04-14: 0 contributions2026-04-15: 0 contributions2026-04-16: 0 contributions2026-04-17: 0 contributions2026-04-18: 0 contributions2026-04-19: 0 contributions2026-04-20: 0 contributions2026-04-21: 0 contributions2026-04-22: 0 contributions2026-04-23: 0 contributions2026-04-24: 0 contributions2026-04-25: 0 contributions2026-04-26: 0 contributions2026-04-27: 0 contributions2026-04-28: 0 contributions2026-04-29: 0 contributions2026-04-30: 0 contributions2026-05-01: 0 contributions2026-05-02: 0 contributions2026-05-03: 8 contributions2026-05-04: 0 contributions2026-05-05: 0 contributions2026-05-06: 0 contributions2026-05-07: 0 contributions2026-05-08: 0 contributions2026-05-09: 19 contributions2026-05-10: 43 contributions2026-05-11: 17 contributions2026-05-12: 0 contributions2026-05-13: 0 contributions2026-05-14: 0 contributions2026-05-15: 0 contributions2026-05-16: 0 contributions2026-05-17: 0 contributions2026-05-18: 0 contributions2026-05-19: 0 contributions2026-05-20: 0 contributions2026-05-21: 0 contributions2026-05-22: 0 contributions2026-05-23: 0 contributions2026-05-24: 0 contributions2026-05-25: 0 contributions2026-05-26: 0 contributions2026-05-27: 0 contributions2026-05-28: 0 contributions2026-05-29: 0 contributions2026-05-30: 0 contributions2026-05-31: 0 contributions2026-06-01: 0 contributions2026-06-02: 0 contributions2026-06-03: 3 contributions \ No newline at end of file diff --git a/public/stats/contributions-light.svg b/public/stats/contributions-light.svg index ea901ff..f3bf2e6 100644 --- a/public/stats/contributions-light.svg +++ b/public/stats/contributions-light.svg @@ -1,6 +1,6 @@ Contribution Graph - JunJulAugSepOctNovDecJanFebMarAprMay + JunJulAugSepOctNovDecJanFebMarAprMay MonWedFri - 2025-06-08: 0 contributions2025-06-09: 0 contributions2025-06-10: 0 contributions2025-06-11: 0 contributions2025-06-12: 1 contributions2025-06-13: 0 contributions2025-06-14: 0 contributions2025-06-15: 2 contributions2025-06-16: 8 contributions2025-06-17: 1 contributions2025-06-18: 15 contributions2025-06-19: 6 contributions2025-06-20: 6 contributions2025-06-21: 0 contributions2025-06-22: 0 contributions2025-06-23: 0 contributions2025-06-24: 0 contributions2025-06-25: 0 contributions2025-06-26: 0 contributions2025-06-27: 0 contributions2025-06-28: 0 contributions2025-06-29: 0 contributions2025-06-30: 0 contributions2025-07-01: 0 contributions2025-07-02: 0 contributions2025-07-03: 0 contributions2025-07-04: 0 contributions2025-07-05: 0 contributions2025-07-06: 0 contributions2025-07-07: 0 contributions2025-07-08: 0 contributions2025-07-09: 0 contributions2025-07-10: 0 contributions2025-07-11: 0 contributions2025-07-12: 0 contributions2025-07-13: 0 contributions2025-07-14: 0 contributions2025-07-15: 0 contributions2025-07-16: 0 contributions2025-07-17: 0 contributions2025-07-18: 0 contributions2025-07-19: 0 contributions2025-07-20: 0 contributions2025-07-21: 0 contributions2025-07-22: 0 contributions2025-07-23: 0 contributions2025-07-24: 0 contributions2025-07-25: 0 contributions2025-07-26: 0 contributions2025-07-27: 0 contributions2025-07-28: 0 contributions2025-07-29: 0 contributions2025-07-30: 0 contributions2025-07-31: 0 contributions2025-08-01: 0 contributions2025-08-02: 0 contributions2025-08-03: 0 contributions2025-08-04: 0 contributions2025-08-05: 0 contributions2025-08-06: 0 contributions2025-08-07: 0 contributions2025-08-08: 0 contributions2025-08-09: 0 contributions2025-08-10: 0 contributions2025-08-11: 0 contributions2025-08-12: 0 contributions2025-08-13: 0 contributions2025-08-14: 0 contributions2025-08-15: 0 contributions2025-08-16: 0 contributions2025-08-17: 0 contributions2025-08-18: 0 contributions2025-08-19: 0 contributions2025-08-20: 0 contributions2025-08-21: 0 contributions2025-08-22: 0 contributions2025-08-23: 0 contributions2025-08-24: 0 contributions2025-08-25: 0 contributions2025-08-26: 0 contributions2025-08-27: 0 contributions2025-08-28: 0 contributions2025-08-29: 0 contributions2025-08-30: 0 contributions2025-08-31: 0 contributions2025-09-01: 0 contributions2025-09-02: 0 contributions2025-09-03: 0 contributions2025-09-04: 0 contributions2025-09-05: 0 contributions2025-09-06: 0 contributions2025-09-07: 0 contributions2025-09-08: 0 contributions2025-09-09: 0 contributions2025-09-10: 0 contributions2025-09-11: 0 contributions2025-09-12: 0 contributions2025-09-13: 0 contributions2025-09-14: 0 contributions2025-09-15: 0 contributions2025-09-16: 0 contributions2025-09-17: 0 contributions2025-09-18: 0 contributions2025-09-19: 0 contributions2025-09-20: 0 contributions2025-09-21: 0 contributions2025-09-22: 0 contributions2025-09-23: 0 contributions2025-09-24: 0 contributions2025-09-25: 0 contributions2025-09-26: 0 contributions2025-09-27: 0 contributions2025-09-28: 0 contributions2025-09-29: 0 contributions2025-09-30: 0 contributions2025-10-01: 0 contributions2025-10-02: 0 contributions2025-10-03: 0 contributions2025-10-04: 0 contributions2025-10-05: 0 contributions2025-10-06: 0 contributions2025-10-07: 0 contributions2025-10-08: 0 contributions2025-10-09: 0 contributions2025-10-10: 0 contributions2025-10-11: 0 contributions2025-10-12: 0 contributions2025-10-13: 0 contributions2025-10-14: 0 contributions2025-10-15: 0 contributions2025-10-16: 0 contributions2025-10-17: 0 contributions2025-10-18: 0 contributions2025-10-19: 0 contributions2025-10-20: 0 contributions2025-10-21: 0 contributions2025-10-22: 0 contributions2025-10-23: 0 contributions2025-10-24: 0 contributions2025-10-25: 0 contributions2025-10-26: 0 contributions2025-10-27: 0 contributions2025-10-28: 0 contributions2025-10-29: 0 contributions2025-10-30: 0 contributions2025-10-31: 0 contributions2025-11-01: 0 contributions2025-11-02: 0 contributions2025-11-03: 0 contributions2025-11-04: 0 contributions2025-11-05: 0 contributions2025-11-06: 0 contributions2025-11-07: 0 contributions2025-11-08: 0 contributions2025-11-09: 0 contributions2025-11-10: 0 contributions2025-11-11: 0 contributions2025-11-12: 0 contributions2025-11-13: 0 contributions2025-11-14: 0 contributions2025-11-15: 0 contributions2025-11-16: 0 contributions2025-11-17: 0 contributions2025-11-18: 0 contributions2025-11-19: 0 contributions2025-11-20: 0 contributions2025-11-21: 0 contributions2025-11-22: 0 contributions2025-11-23: 0 contributions2025-11-24: 0 contributions2025-11-25: 0 contributions2025-11-26: 0 contributions2025-11-27: 0 contributions2025-11-28: 0 contributions2025-11-29: 0 contributions2025-11-30: 0 contributions2025-12-01: 0 contributions2025-12-02: 0 contributions2025-12-03: 0 contributions2025-12-04: 0 contributions2025-12-05: 0 contributions2025-12-06: 0 contributions2025-12-07: 0 contributions2025-12-08: 0 contributions2025-12-09: 0 contributions2025-12-10: 0 contributions2025-12-11: 0 contributions2025-12-12: 0 contributions2025-12-13: 0 contributions2025-12-14: 0 contributions2025-12-15: 0 contributions2025-12-16: 0 contributions2025-12-17: 0 contributions2025-12-18: 0 contributions2025-12-19: 0 contributions2025-12-20: 0 contributions2025-12-21: 0 contributions2025-12-22: 0 contributions2025-12-23: 0 contributions2025-12-24: 0 contributions2025-12-25: 0 contributions2025-12-26: 0 contributions2025-12-27: 0 contributions2025-12-28: 0 contributions2025-12-29: 0 contributions2025-12-30: 0 contributions2025-12-31: 0 contributions2026-01-01: 0 contributions2026-01-02: 0 contributions2026-01-03: 0 contributions2026-01-04: 0 contributions2026-01-05: 0 contributions2026-01-06: 0 contributions2026-01-07: 0 contributions2026-01-08: 0 contributions2026-01-09: 0 contributions2026-01-10: 0 contributions2026-01-11: 0 contributions2026-01-12: 0 contributions2026-01-13: 0 contributions2026-01-14: 0 contributions2026-01-15: 0 contributions2026-01-16: 0 contributions2026-01-17: 0 contributions2026-01-18: 0 contributions2026-01-19: 0 contributions2026-01-20: 0 contributions2026-01-21: 0 contributions2026-01-22: 0 contributions2026-01-23: 0 contributions2026-01-24: 0 contributions2026-01-25: 0 contributions2026-01-26: 0 contributions2026-01-27: 0 contributions2026-01-28: 0 contributions2026-01-29: 0 contributions2026-01-30: 0 contributions2026-01-31: 0 contributions2026-02-01: 0 contributions2026-02-02: 0 contributions2026-02-03: 0 contributions2026-02-04: 0 contributions2026-02-05: 0 contributions2026-02-06: 0 contributions2026-02-07: 0 contributions2026-02-08: 14 contributions2026-02-09: 8 contributions2026-02-10: 1 contributions2026-02-11: 0 contributions2026-02-12: 4 contributions2026-02-13: 0 contributions2026-02-14: 0 contributions2026-02-15: 20 contributions2026-02-16: 34 contributions2026-02-17: 0 contributions2026-02-18: 0 contributions2026-02-19: 18 contributions2026-02-20: 55 contributions2026-02-21: 4 contributions2026-02-22: 0 contributions2026-02-23: 6 contributions2026-02-24: 0 contributions2026-02-25: 1 contributions2026-02-26: 0 contributions2026-02-27: 0 contributions2026-02-28: 17 contributions2026-03-01: 7 contributions2026-03-02: 11 contributions2026-03-03: 0 contributions2026-03-04: 0 contributions2026-03-05: 0 contributions2026-03-06: 3 contributions2026-03-07: 0 contributions2026-03-08: 0 contributions2026-03-09: 24 contributions2026-03-10: 0 contributions2026-03-11: 0 contributions2026-03-12: 0 contributions2026-03-13: 15 contributions2026-03-14: 45 contributions2026-03-15: 9 contributions2026-03-16: 0 contributions2026-03-17: 5 contributions2026-03-18: 2 contributions2026-03-19: 0 contributions2026-03-20: 6 contributions2026-03-21: 0 contributions2026-03-22: 0 contributions2026-03-23: 3 contributions2026-03-24: 0 contributions2026-03-25: 0 contributions2026-03-26: 0 contributions2026-03-27: 0 contributions2026-03-28: 6 contributions2026-03-29: 5 contributions2026-03-30: 9 contributions2026-03-31: 0 contributions2026-04-01: 0 contributions2026-04-02: 0 contributions2026-04-03: 0 contributions2026-04-04: 0 contributions2026-04-05: 0 contributions2026-04-06: 0 contributions2026-04-07: 0 contributions2026-04-08: 0 contributions2026-04-09: 0 contributions2026-04-10: 0 contributions2026-04-11: 0 contributions2026-04-12: 0 contributions2026-04-13: 0 contributions2026-04-14: 0 contributions2026-04-15: 0 contributions2026-04-16: 0 contributions2026-04-17: 0 contributions2026-04-18: 0 contributions2026-04-19: 0 contributions2026-04-20: 0 contributions2026-04-21: 0 contributions2026-04-22: 0 contributions2026-04-23: 0 contributions2026-04-24: 0 contributions2026-04-25: 0 contributions2026-04-26: 0 contributions2026-04-27: 0 contributions2026-04-28: 0 contributions2026-04-29: 0 contributions2026-04-30: 0 contributions2026-05-01: 0 contributions2026-05-02: 0 contributions2026-05-03: 8 contributions2026-05-04: 0 contributions2026-05-05: 0 contributions2026-05-06: 0 contributions2026-05-07: 0 contributions2026-05-08: 0 contributions2026-05-09: 18 contributions2026-05-10: 44 contributions2026-05-11: 17 contributions2026-05-12: 0 contributions2026-05-13: 0 contributions2026-05-14: 0 contributions2026-05-15: 0 contributions2026-05-16: 0 contributions2026-05-17: 0 contributions2026-05-18: 0 contributions2026-05-19: 0 contributions2026-05-20: 0 contributions2026-05-21: 0 contributions2026-05-22: 0 contributions2026-05-23: 0 contributions2026-05-24: 0 contributions2026-05-25: 0 contributions2026-05-26: 0 contributions2026-05-27: 0 contributions2026-05-28: 0 contributions2026-05-29: 0 contributions2026-05-30: 0 contributions2026-05-31: 0 contributions2026-06-01: 0 contributions2026-06-02: 0 contributions2026-06-03: 3 contributions + 2025-06-08: 0 contributions2025-06-09: 0 contributions2025-06-10: 0 contributions2025-06-11: 0 contributions2025-06-12: 1 contributions2025-06-13: 0 contributions2025-06-14: 0 contributions2025-06-15: 3 contributions2025-06-16: 7 contributions2025-06-17: 1 contributions2025-06-18: 15 contributions2025-06-19: 7 contributions2025-06-20: 5 contributions2025-06-21: 0 contributions2025-06-22: 0 contributions2025-06-23: 0 contributions2025-06-24: 0 contributions2025-06-25: 0 contributions2025-06-26: 0 contributions2025-06-27: 0 contributions2025-06-28: 0 contributions2025-06-29: 0 contributions2025-06-30: 0 contributions2025-07-01: 0 contributions2025-07-02: 0 contributions2025-07-03: 0 contributions2025-07-04: 0 contributions2025-07-05: 0 contributions2025-07-06: 0 contributions2025-07-07: 0 contributions2025-07-08: 0 contributions2025-07-09: 0 contributions2025-07-10: 0 contributions2025-07-11: 0 contributions2025-07-12: 0 contributions2025-07-13: 0 contributions2025-07-14: 0 contributions2025-07-15: 0 contributions2025-07-16: 0 contributions2025-07-17: 0 contributions2025-07-18: 0 contributions2025-07-19: 0 contributions2025-07-20: 0 contributions2025-07-21: 0 contributions2025-07-22: 0 contributions2025-07-23: 0 contributions2025-07-24: 0 contributions2025-07-25: 0 contributions2025-07-26: 0 contributions2025-07-27: 0 contributions2025-07-28: 0 contributions2025-07-29: 0 contributions2025-07-30: 0 contributions2025-07-31: 0 contributions2025-08-01: 0 contributions2025-08-02: 0 contributions2025-08-03: 0 contributions2025-08-04: 0 contributions2025-08-05: 0 contributions2025-08-06: 0 contributions2025-08-07: 0 contributions2025-08-08: 0 contributions2025-08-09: 0 contributions2025-08-10: 0 contributions2025-08-11: 0 contributions2025-08-12: 0 contributions2025-08-13: 0 contributions2025-08-14: 0 contributions2025-08-15: 0 contributions2025-08-16: 0 contributions2025-08-17: 0 contributions2025-08-18: 0 contributions2025-08-19: 0 contributions2025-08-20: 0 contributions2025-08-21: 0 contributions2025-08-22: 0 contributions2025-08-23: 0 contributions2025-08-24: 0 contributions2025-08-25: 0 contributions2025-08-26: 0 contributions2025-08-27: 0 contributions2025-08-28: 0 contributions2025-08-29: 0 contributions2025-08-30: 0 contributions2025-08-31: 0 contributions2025-09-01: 0 contributions2025-09-02: 0 contributions2025-09-03: 0 contributions2025-09-04: 0 contributions2025-09-05: 0 contributions2025-09-06: 0 contributions2025-09-07: 0 contributions2025-09-08: 0 contributions2025-09-09: 0 contributions2025-09-10: 0 contributions2025-09-11: 0 contributions2025-09-12: 0 contributions2025-09-13: 0 contributions2025-09-14: 0 contributions2025-09-15: 0 contributions2025-09-16: 0 contributions2025-09-17: 0 contributions2025-09-18: 0 contributions2025-09-19: 0 contributions2025-09-20: 0 contributions2025-09-21: 0 contributions2025-09-22: 0 contributions2025-09-23: 0 contributions2025-09-24: 0 contributions2025-09-25: 0 contributions2025-09-26: 0 contributions2025-09-27: 0 contributions2025-09-28: 0 contributions2025-09-29: 0 contributions2025-09-30: 0 contributions2025-10-01: 0 contributions2025-10-02: 0 contributions2025-10-03: 0 contributions2025-10-04: 0 contributions2025-10-05: 0 contributions2025-10-06: 0 contributions2025-10-07: 0 contributions2025-10-08: 0 contributions2025-10-09: 0 contributions2025-10-10: 0 contributions2025-10-11: 0 contributions2025-10-12: 0 contributions2025-10-13: 0 contributions2025-10-14: 0 contributions2025-10-15: 0 contributions2025-10-16: 0 contributions2025-10-17: 0 contributions2025-10-18: 0 contributions2025-10-19: 0 contributions2025-10-20: 0 contributions2025-10-21: 0 contributions2025-10-22: 0 contributions2025-10-23: 0 contributions2025-10-24: 0 contributions2025-10-25: 0 contributions2025-10-26: 0 contributions2025-10-27: 0 contributions2025-10-28: 0 contributions2025-10-29: 0 contributions2025-10-30: 0 contributions2025-10-31: 0 contributions2025-11-01: 0 contributions2025-11-02: 0 contributions2025-11-03: 0 contributions2025-11-04: 0 contributions2025-11-05: 0 contributions2025-11-06: 0 contributions2025-11-07: 0 contributions2025-11-08: 0 contributions2025-11-09: 0 contributions2025-11-10: 0 contributions2025-11-11: 0 contributions2025-11-12: 0 contributions2025-11-13: 0 contributions2025-11-14: 0 contributions2025-11-15: 0 contributions2025-11-16: 0 contributions2025-11-17: 0 contributions2025-11-18: 0 contributions2025-11-19: 0 contributions2025-11-20: 0 contributions2025-11-21: 0 contributions2025-11-22: 0 contributions2025-11-23: 0 contributions2025-11-24: 0 contributions2025-11-25: 0 contributions2025-11-26: 0 contributions2025-11-27: 0 contributions2025-11-28: 0 contributions2025-11-29: 0 contributions2025-11-30: 0 contributions2025-12-01: 0 contributions2025-12-02: 0 contributions2025-12-03: 0 contributions2025-12-04: 0 contributions2025-12-05: 0 contributions2025-12-06: 0 contributions2025-12-07: 0 contributions2025-12-08: 0 contributions2025-12-09: 0 contributions2025-12-10: 0 contributions2025-12-11: 0 contributions2025-12-12: 0 contributions2025-12-13: 0 contributions2025-12-14: 0 contributions2025-12-15: 0 contributions2025-12-16: 0 contributions2025-12-17: 0 contributions2025-12-18: 0 contributions2025-12-19: 0 contributions2025-12-20: 0 contributions2025-12-21: 0 contributions2025-12-22: 0 contributions2025-12-23: 0 contributions2025-12-24: 0 contributions2025-12-25: 0 contributions2025-12-26: 0 contributions2025-12-27: 0 contributions2025-12-28: 0 contributions2025-12-29: 0 contributions2025-12-30: 0 contributions2025-12-31: 0 contributions2026-01-01: 0 contributions2026-01-02: 0 contributions2026-01-03: 0 contributions2026-01-04: 0 contributions2026-01-05: 0 contributions2026-01-06: 0 contributions2026-01-07: 0 contributions2026-01-08: 0 contributions2026-01-09: 0 contributions2026-01-10: 0 contributions2026-01-11: 0 contributions2026-01-12: 0 contributions2026-01-13: 0 contributions2026-01-14: 0 contributions2026-01-15: 0 contributions2026-01-16: 0 contributions2026-01-17: 0 contributions2026-01-18: 0 contributions2026-01-19: 0 contributions2026-01-20: 0 contributions2026-01-21: 0 contributions2026-01-22: 0 contributions2026-01-23: 0 contributions2026-01-24: 0 contributions2026-01-25: 0 contributions2026-01-26: 0 contributions2026-01-27: 0 contributions2026-01-28: 0 contributions2026-01-29: 0 contributions2026-01-30: 0 contributions2026-01-31: 0 contributions2026-02-01: 0 contributions2026-02-02: 0 contributions2026-02-03: 0 contributions2026-02-04: 0 contributions2026-02-05: 0 contributions2026-02-06: 0 contributions2026-02-07: 0 contributions2026-02-08: 15 contributions2026-02-09: 7 contributions2026-02-10: 1 contributions2026-02-11: 0 contributions2026-02-12: 4 contributions2026-02-13: 0 contributions2026-02-14: 0 contributions2026-02-15: 21 contributions2026-02-16: 33 contributions2026-02-17: 0 contributions2026-02-18: 0 contributions2026-02-19: 18 contributions2026-02-20: 55 contributions2026-02-21: 4 contributions2026-02-22: 0 contributions2026-02-23: 6 contributions2026-02-24: 0 contributions2026-02-25: 1 contributions2026-02-26: 0 contributions2026-02-27: 0 contributions2026-02-28: 17 contributions2026-03-01: 7 contributions2026-03-02: 11 contributions2026-03-03: 0 contributions2026-03-04: 0 contributions2026-03-05: 0 contributions2026-03-06: 3 contributions2026-03-07: 0 contributions2026-03-08: 0 contributions2026-03-09: 24 contributions2026-03-10: 0 contributions2026-03-11: 0 contributions2026-03-12: 0 contributions2026-03-13: 15 contributions2026-03-14: 45 contributions2026-03-15: 9 contributions2026-03-16: 0 contributions2026-03-17: 5 contributions2026-03-18: 2 contributions2026-03-19: 0 contributions2026-03-20: 6 contributions2026-03-21: 0 contributions2026-03-22: 0 contributions2026-03-23: 3 contributions2026-03-24: 0 contributions2026-03-25: 0 contributions2026-03-26: 0 contributions2026-03-27: 0 contributions2026-03-28: 6 contributions2026-03-29: 5 contributions2026-03-30: 9 contributions2026-03-31: 0 contributions2026-04-01: 0 contributions2026-04-02: 0 contributions2026-04-03: 0 contributions2026-04-04: 0 contributions2026-04-05: 0 contributions2026-04-06: 0 contributions2026-04-07: 0 contributions2026-04-08: 0 contributions2026-04-09: 0 contributions2026-04-10: 0 contributions2026-04-11: 0 contributions2026-04-12: 0 contributions2026-04-13: 0 contributions2026-04-14: 0 contributions2026-04-15: 0 contributions2026-04-16: 0 contributions2026-04-17: 0 contributions2026-04-18: 0 contributions2026-04-19: 0 contributions2026-04-20: 0 contributions2026-04-21: 0 contributions2026-04-22: 0 contributions2026-04-23: 0 contributions2026-04-24: 0 contributions2026-04-25: 0 contributions2026-04-26: 0 contributions2026-04-27: 0 contributions2026-04-28: 0 contributions2026-04-29: 0 contributions2026-04-30: 0 contributions2026-05-01: 0 contributions2026-05-02: 0 contributions2026-05-03: 8 contributions2026-05-04: 0 contributions2026-05-05: 0 contributions2026-05-06: 0 contributions2026-05-07: 0 contributions2026-05-08: 0 contributions2026-05-09: 19 contributions2026-05-10: 43 contributions2026-05-11: 17 contributions2026-05-12: 0 contributions2026-05-13: 0 contributions2026-05-14: 0 contributions2026-05-15: 0 contributions2026-05-16: 0 contributions2026-05-17: 0 contributions2026-05-18: 0 contributions2026-05-19: 0 contributions2026-05-20: 0 contributions2026-05-21: 0 contributions2026-05-22: 0 contributions2026-05-23: 0 contributions2026-05-24: 0 contributions2026-05-25: 0 contributions2026-05-26: 0 contributions2026-05-27: 0 contributions2026-05-28: 0 contributions2026-05-29: 0 contributions2026-05-30: 0 contributions2026-05-31: 0 contributions2026-06-01: 0 contributions2026-06-02: 0 contributions2026-06-03: 3 contributions \ No newline at end of file diff --git a/public/stats/repo-claude-hindsight-dark.svg b/public/stats/repo-claude-hindsight-dark.svg new file mode 100644 index 0000000..d2e8995 --- /dev/null +++ b/public/stats/repo-claude-hindsight-dark.svg @@ -0,0 +1,13 @@ + + + + + + claude-hindsight + Claude Hindsight is a powerful observability tool + for Claude Code that transforms raw JSONL… + + Rust + ★ 19 + ⑂ 2 + \ No newline at end of file diff --git a/public/stats/repo-claude-hindsight-light.svg b/public/stats/repo-claude-hindsight-light.svg new file mode 100644 index 0000000..5b307ec --- /dev/null +++ b/public/stats/repo-claude-hindsight-light.svg @@ -0,0 +1,13 @@ + + + + + + claude-hindsight + Claude Hindsight is a powerful observability tool + for Claude Code that transforms raw JSONL… + + Rust + ★ 19 + ⑂ 2 + \ No newline at end of file diff --git a/public/stats/stats-dark.svg b/public/stats/stats-dark.svg index bd249e8..6403185 100644 --- a/public/stats/stats-dark.svg +++ b/public/stats/stats-dark.svg @@ -20,7 +20,7 @@ PRs Merged: - 33 + 35 diff --git a/public/stats/stats-light.svg b/public/stats/stats-light.svg index d05b8cc..36f9253 100644 --- a/public/stats/stats-light.svg +++ b/public/stats/stats-light.svg @@ -20,7 +20,7 @@ PRs Merged: - 33 + 35 diff --git a/public/stats/streak-dark.svg b/public/stats/streak-dark.svg index c28e20d..97febac 100644 --- a/public/stats/streak-dark.svg +++ b/public/stats/streak-dark.svg @@ -15,6 +15,6 @@ Longest Streak - + \ No newline at end of file diff --git a/public/stats/streak-light.svg b/public/stats/streak-light.svg index b1f630d..1a5e679 100644 --- a/public/stats/streak-light.svg +++ b/public/stats/streak-light.svg @@ -15,6 +15,6 @@ Longest Streak - + \ No newline at end of file diff --git a/src/app/about/page.tsx b/src/app/about/page.tsx index e371336..757b3ce 100644 --- a/src/app/about/page.tsx +++ b/src/app/about/page.tsx @@ -14,7 +14,8 @@ import { generatePageMetadata } from '@/lib/utils'; */ export const metadata = generatePageMetadata({ title: 'About Me', - description: 'Software Engineer II specializing in AI integration, full-stack development, and performance optimization. Based in Medellín, Colombia.', + description: + 'Senior Software Engineer specializing in AI integration, full-stack development, and performance optimization. Based in Medellín, Colombia.', path: '/about', }); diff --git a/src/app/experiments/[slug]/opengraph-image.tsx b/src/app/experiments/[slug]/opengraph-image.tsx new file mode 100644 index 0000000..77200f7 --- /dev/null +++ b/src/app/experiments/[slug]/opengraph-image.tsx @@ -0,0 +1,99 @@ +import { ImageResponse } from 'next/og'; +import { contentService } from '@/lib/services'; +import { APP_CONFIG } from '@/lib/constants'; + +export const alt = 'Blog post on codestz.dev'; +export const size = { width: 1200, height: 630 }; +export const contentType = 'image/png'; + +const PURPLE = '#7c3aed'; +const BG = '#0a0a0a'; +const FG = '#fafafa'; + +export default async function OgImage({ params }: { params: Promise<{ slug: string }> }) { + const { slug } = await params; + const result = await contentService.getPostBySlug(slug); + const post = result.success ? result.data : null; + + const title = post?.title ?? 'codestz.dev'; + const tags = post?.tags?.slice(0, 4) ?? []; + const readTime = post?.readTime ?? ''; + const date = post?.publishedAt + ? new Date(post.publishedAt).toLocaleDateString('en-US', { + month: 'short', + year: 'numeric', + timeZone: 'UTC', + }) + : ''; + + return new ImageResponse( +
+
+
+
CODESTZ.DEV
+
+ +
50 ? 64 : 78, + fontWeight: 800, + lineHeight: 1.05, + letterSpacing: '-1px', + }} + > + {title} +
+ +
+
+ {tags.map((tag) => ( +
+ {tag} +
+ ))} +
+
+ {[date, readTime].filter(Boolean).join(' · ')} + {APP_CONFIG.author.name} +
+
+
, + { ...size } + ); +} diff --git a/src/app/experiments/[slug]/page.tsx b/src/app/experiments/[slug]/page.tsx index f3a37db..a30b402 100644 --- a/src/app/experiments/[slug]/page.tsx +++ b/src/app/experiments/[slug]/page.tsx @@ -5,12 +5,13 @@ import Image from 'next/image'; import { Section } from '@/components/sections'; import { Button, Badge } from '@/components/ui'; import { ReadingProgressBar, SeriesNav, SeriesPager } from '@/components/blog'; +import { JsonLd } from '@/components/seo'; import { contentService } from '@/lib/services'; import { ROUTES } from '@/lib/constants'; import type { Metadata } from 'next'; import remarkGfm from 'remark-gfm'; import { mdxComponents } from '../../../../mdx-components'; -import { generateBlogPostMetadata, formatDate } from '@/lib/utils'; +import { generateBlogPostMetadata, formatDate, articleJsonLd } from '@/lib/utils'; import type { BlogPostPageProps } from './page.types'; /** @@ -72,6 +73,8 @@ export default async function ExperimentPage({ params }: BlogPostPageProps) { return (
+ + {/* Reading Progress Bar */} diff --git a/src/app/feed/route.ts b/src/app/feed/route.ts index 453b585..3040bbf 100644 --- a/src/app/feed/route.ts +++ b/src/app/feed/route.ts @@ -25,13 +25,14 @@ export async function GET() { ${escapeXml(post.description)} ${new Date(post.publishedAt).toUTCString()} ${escapeXml(APP_CONFIG.author.email)} (${escapeXml(APP_CONFIG.author.name)}) + ${escapeXml(post.readTime)} ${post.tags.map((tag) => `${escapeXml(tag)}`).join('\n ')} ` ) .join('\n'); const rss = ` - + ${escapeXml(APP_CONFIG.name)} - Blog ${SITE_URL} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 4fae3b0..124922b 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -4,7 +4,9 @@ import { Analytics } from '@vercel/analytics/react'; import { SpeedInsights } from '@vercel/speed-insights/next'; import { ThemeProvider } from '@/components/providers'; import { Header, Footer } from '@/components/layout'; +import { JsonLd } from '@/components/seo'; import { APP_CONFIG } from '@/lib/constants'; +import { personJsonLd, websiteJsonLd } from '@/lib/utils'; import './globals.css'; // Syne for headings (bold) @@ -24,6 +26,7 @@ const spaceMono = Space_Mono({ }); export const metadata: Metadata = { + metadataBase: new URL(process.env.NEXT_PUBLIC_SITE_URL || 'https://codestz.dev'), title: APP_CONFIG.title, description: APP_CONFIG.description, icons: { @@ -43,6 +46,10 @@ export default function RootLayout({ }>) { return ( + + + +
diff --git a/src/app/opengraph-image.tsx b/src/app/opengraph-image.tsx new file mode 100644 index 0000000..1221bda --- /dev/null +++ b/src/app/opengraph-image.tsx @@ -0,0 +1,45 @@ +import { ImageResponse } from 'next/og'; +import { APP_CONFIG } from '@/lib/constants'; + +export const alt = 'codestz.dev — Esteban Estrada'; +export const size = { width: 1200, height: 630 }; +export const contentType = 'image/png'; + +const PURPLE = '#7c3aed'; +const BG = '#0a0a0a'; +const FG = '#fafafa'; + +export default function OgImage() { + return new ImageResponse( +
+
+
+
CODESTZ.DEV
+
+
+ {APP_CONFIG.author.name} +
+
+ {APP_CONFIG.author.role} +
+
+ Developer tools that make AI agents smarter — Rust, TypeScript, Go. +
+
, + { ...size } + ); +} diff --git a/src/app/robots.ts b/src/app/robots.ts new file mode 100644 index 0000000..98e563d --- /dev/null +++ b/src/app/robots.ts @@ -0,0 +1,15 @@ +import { MetadataRoute } from 'next'; + +const SITE_URL = process.env.NEXT_PUBLIC_SITE_URL || 'https://codestz.dev'; + +export default function robots(): MetadataRoute.Robots { + return { + rules: { + userAgent: '*', + allow: '/', + disallow: ['/api/'], + }, + sitemap: `${SITE_URL}/sitemap.xml`, + host: SITE_URL, + }; +} diff --git a/src/app/sitemap.ts b/src/app/sitemap.ts index 0aa30fe..ee34bfc 100644 --- a/src/app/sitemap.ts +++ b/src/app/sitemap.ts @@ -2,15 +2,10 @@ import { MetadataRoute } from 'next'; import { contentService } from '@/lib/services'; export default async function sitemap(): Promise { - const baseUrl = 'https://estebanestrada.dev'; // Update with your actual domain + const baseUrl = process.env.NEXT_PUBLIC_SITE_URL || 'https://codestz.dev'; // Static routes - const routes = [ - '', - '/about', - '/experiments', - '/experience', - ].map((route) => ({ + const routes = ['', '/about', '/experiments', '/experience'].map((route) => ({ url: `${baseUrl}${route}`, lastModified: new Date().toISOString(), changeFrequency: 'weekly' as const, diff --git a/src/components/about/ExperienceTimeline/ExperienceTimeline.tsx b/src/components/about/ExperienceTimeline/ExperienceTimeline.tsx index 2175abb..282391e 100644 --- a/src/components/about/ExperienceTimeline/ExperienceTimeline.tsx +++ b/src/components/about/ExperienceTimeline/ExperienceTimeline.tsx @@ -11,7 +11,7 @@ import type { ExperienceTimelineProps, Experience } from './ExperienceTimeline.t const EXPERIENCES: Experience[] = [ { company: 'Recurly', - role: 'Software Engineer II', + role: 'Senior Software Engineer', duration: 'July 2025 - Present', current: true, achievements: [ @@ -32,7 +32,14 @@ const EXPERIENCES: Experience[] = [ 'Built responsive UIs with React and Next.js', 'Designed robust APIs for AI-driven workflows', ], - technologies: ['TypeScript', 'Python', 'React', 'Next.js', 'AI Integration', 'Autonomous Agents'], + technologies: [ + 'TypeScript', + 'Python', + 'React', + 'Next.js', + 'AI Integration', + 'Autonomous Agents', + ], }, { company: '8base', @@ -114,7 +121,10 @@ export function ExperienceTimeline({ className }: ExperienceTimelineProps) {
{/* Experience Cards */} -
+
{EXPERIENCES.map((exp, idx) => (
{/* Timeline Dot */} @@ -142,7 +152,9 @@ export function ExperienceTimeline({ className }: ExperienceTimelineProps) { )}
{exp.role}
-
{exp.duration}
+
+ {exp.duration} +
{/* Achievements */} diff --git a/src/components/about/HeroIntroduction/HeroIntroduction.tsx b/src/components/about/HeroIntroduction/HeroIntroduction.tsx index 13902f8..0b6f6c3 100644 --- a/src/components/about/HeroIntroduction/HeroIntroduction.tsx +++ b/src/components/about/HeroIntroduction/HeroIntroduction.tsx @@ -16,7 +16,7 @@ const STATS: StatCard[] = [ ]; const TITLES = [ - 'Software Engineer II', + 'Senior Software Engineer', 'AI Integration Specialist', 'Full-Stack Developer', 'Performance Optimizer', @@ -122,7 +122,8 @@ export function HeroIntroduction({ className }: HeroIntroductionProps) { {/* Intro */}

Building scalable, high-performance applications with modern full-stack technologies. - Passionate about AI integration, autonomous agents, and creating exceptional user experiences. + Passionate about AI integration, autonomous agents, and creating exceptional user + experiences.

{/* Download Resume */} @@ -146,8 +147,12 @@ export function HeroIntroduction({ className }: HeroIntroductionProps) { key={idx} className="border-[3px] border-foreground bg-bg-elevated shadow-[6px_6px_0px_0px] shadow-foreground p-4 sm:p-6 text-center" > -
{stat.value}
-
{stat.label}
+
+ {stat.value} +
+
+ {stat.label} +
))}
diff --git a/src/components/seo/JsonLd.tsx b/src/components/seo/JsonLd.tsx new file mode 100644 index 0000000..72a9fe7 --- /dev/null +++ b/src/components/seo/JsonLd.tsx @@ -0,0 +1,9 @@ +/** + * Renders a JSON-LD structured-data script tag. + * Server component — safe to embed schema.org objects for SEO rich results. + */ +export function JsonLd({ data }: { data: Record }) { + return ( +