doc-fetch-cli 2.0.4 → 2.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/bin/doc-fetch_darwin_amd64 +0 -0
- package/bin/doc-fetch_windows_amd64.exe +0 -0
- package/doc-fetch +0 -0
- package/doc-fetch_darwin_amd64 +0 -0
- package/doc-fetch_darwin_arm64 +0 -0
- package/doc-fetch_linux_amd64 +0 -0
- package/doc-fetch_windows_amd64.exe +0 -0
- package/package.json +1 -1
- package/website/BLOG-SETUP-SUMMARY.md +385 -0
- package/website/DEPLOYMENT.md +189 -0
- package/website/LAUNCH-CHECKLIST.md +134 -0
- package/website/README.md +75 -0
- package/website/SEO-STRATEGY.md +347 -0
- package/website/URL-STRUCTURE.md +334 -0
- package/website/WEBSITE-SUMMARY.md +246 -0
- package/website/package-lock.json +1628 -0
- package/website/package.json +39 -0
- package/website/pnpm-lock.yaml +1061 -0
- package/website/src/app.d.ts +13 -0
- package/website/src/app.html +11 -0
- package/website/src/lib/actions/addCopyButtons.ts +73 -0
- package/website/src/lib/assets/favicon.svg +1 -0
- package/website/src/lib/components/CopyCodeButton.svelte +97 -0
- package/website/src/lib/components/DarkModeToggle.svelte +140 -0
- package/website/src/lib/components/ReadingProgress.svelte +36 -0
- package/website/src/lib/components/RelatedPosts.svelte +151 -0
- package/website/src/lib/components/TableOfContents.svelte +184 -0
- package/website/src/lib/index.ts +1 -0
- package/website/src/lib/posts/convert-docs-to-markdown.md +506 -0
- package/website/src/routes/+layout.svelte +59 -0
- package/website/src/routes/+page.svelte +1033 -0
- package/website/src/routes/about/+page.svelte +607 -0
- package/website/src/routes/blog/+page.svelte +486 -0
- package/website/src/routes/blog/[slug]/+page.svelte +988 -0
- package/website/src/routes/blog/[slug]/+page.ts +53 -0
- package/website/src/routes/sitemap.xml/+server.ts +62 -0
- package/website/static/favicon.svg +10 -0
- package/website/static/og.png +2 -0
- package/website/static/og.svg +26 -0
- package/website/static/robots.txt +43 -0
- package/website/svelte.config.js +13 -0
- package/website/tsconfig.json +20 -0
- package/website/vite.config.ts +6 -0
|
@@ -0,0 +1,988 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { page } from '$app/stores';
|
|
3
|
+
import type { PageData } from './$types';
|
|
4
|
+
import { marked } from 'marked';
|
|
5
|
+
import { onMount } from 'svelte';
|
|
6
|
+
import TableOfContents from '$lib/components/TableOfContents.svelte';
|
|
7
|
+
import ReadingProgress from '$lib/components/ReadingProgress.svelte';
|
|
8
|
+
import RelatedPosts from '$lib/components/RelatedPosts.svelte';
|
|
9
|
+
import { addCopyButtons } from '$lib/actions/addCopyButtons';
|
|
10
|
+
|
|
11
|
+
let { data }: { data: PageData } = $props();
|
|
12
|
+
let post = data.post;
|
|
13
|
+
|
|
14
|
+
const baseUrl = 'https://docfetch.dev';
|
|
15
|
+
const canonicalUrl = `${baseUrl}/blog/${post.slug}`;
|
|
16
|
+
|
|
17
|
+
// Animated read time counter
|
|
18
|
+
let animatedReadTime = '0 min read';
|
|
19
|
+
|
|
20
|
+
onMount(() => {
|
|
21
|
+
// Extract number from post.readTime (e.g., "8 min read" → 8)
|
|
22
|
+
const match = post.readTime.match(/(\d+)/);
|
|
23
|
+
const targetMinutes = match ? parseInt(match[1]) : 0;
|
|
24
|
+
|
|
25
|
+
// Animate from 0 to target
|
|
26
|
+
let current = 0;
|
|
27
|
+
const duration = 1000; // 1 second animation
|
|
28
|
+
const startTime = performance.now();
|
|
29
|
+
|
|
30
|
+
function animate(currentTime: number) {
|
|
31
|
+
const elapsed = currentTime - startTime;
|
|
32
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
33
|
+
|
|
34
|
+
// Ease-out quart for smooth deceleration
|
|
35
|
+
const eased = 1 - Math.pow(1 - progress, 4);
|
|
36
|
+
current = Math.floor(eased * targetMinutes);
|
|
37
|
+
|
|
38
|
+
animatedReadTime = `${current} min read`;
|
|
39
|
+
|
|
40
|
+
if (progress < 1) {
|
|
41
|
+
requestAnimationFrame(animate);
|
|
42
|
+
} else {
|
|
43
|
+
animatedReadTime = post.readTime; // Ensure final value matches exactly
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
requestAnimationFrame(animate);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// For now, using placeholder content - will load from markdown file in production
|
|
51
|
+
const placeholderContent = `
|
|
52
|
+
## Quick Start
|
|
53
|
+
|
|
54
|
+
Install DocFetch and convert your first documentation site:
|
|
55
|
+
|
|
56
|
+
\`\`\`bash
|
|
57
|
+
npm install -g doc-fetch
|
|
58
|
+
doc-fetch --url https://golang.org/doc/ --output go-docs.md --llm-txt
|
|
59
|
+
\`\`\`
|
|
60
|
+
|
|
61
|
+
**Full article coming soon!** This is a placeholder until we properly integrate markdown loading.
|
|
62
|
+
|
|
63
|
+
The complete guide covers:
|
|
64
|
+
- Why LLMs need complete documentation context
|
|
65
|
+
- Three methods compared (manual, extensions, automated)
|
|
66
|
+
- Step-by-step DocFetch tutorial
|
|
67
|
+
- LLM.txt indexing explained
|
|
68
|
+
- Token optimization tips
|
|
69
|
+
- Real-world examples
|
|
70
|
+
|
|
71
|
+
Stay tuned!
|
|
72
|
+
`;
|
|
73
|
+
|
|
74
|
+
const htmlContent = marked(placeholderContent);
|
|
75
|
+
|
|
76
|
+
// Helper functions for related posts
|
|
77
|
+
function getRelatedPostTitle(slug: string): string {
|
|
78
|
+
const titles: Record<string, string> = {
|
|
79
|
+
'llm-txt-index-guide': 'LLM.txt Explained: The Secret to Better AI Context Navigation',
|
|
80
|
+
'ai-agent-documentation-problem': 'Why AI Agents Can\'t Read Documentation (And How to Fix It)',
|
|
81
|
+
'best-practices-rag-context-preparation': 'RAG Context Preparation: 7 Best Practices from Production',
|
|
82
|
+
'compare-documentation-fetchers': 'Documentation Fetchers Compared: DocFetch vs Alternatives',
|
|
83
|
+
'token-efficiency-llm-context': 'Token Efficiency: How to Fit More Context in Less Tokens'
|
|
84
|
+
};
|
|
85
|
+
return titles[slug] || 'Related Article';
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function getRelatedPostExcerpt(slug: string): string {
|
|
89
|
+
const excerpts: Record<string, string> = {
|
|
90
|
+
'llm-txt-index-guide': 'What is llm.txt? How does it supercharge your AI agents? Complete guide to semantic documentation indexing.',
|
|
91
|
+
'ai-agent-documentation-problem': 'The fundamental problem with AI agents and web navigation. Real-world solutions for production deployments.',
|
|
92
|
+
'best-practices-rag-context-preparation': 'Learn from real deployments: chunking strategies, metadata enrichment, and indexing approaches that work.',
|
|
93
|
+
'compare-documentation-fetchers': 'Honest comparison of tools for converting docs to markdown. Features, limitations, and when to use each.',
|
|
94
|
+
'token-efficiency-llm-context': 'Reduce LLM costs by 60%+ with smart context preparation. Cleaning strategies and compression techniques.'
|
|
95
|
+
};
|
|
96
|
+
return excerpts[slug] || 'Read more about this topic.';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function getRelativeTime(dateStr: string): string {
|
|
100
|
+
const date = new Date(dateStr);
|
|
101
|
+
const now = new Date();
|
|
102
|
+
const diffMs = now.getTime() - date.getTime();
|
|
103
|
+
const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24));
|
|
104
|
+
|
|
105
|
+
if (diffDays === 0) return 'today';
|
|
106
|
+
if (diffDays === 1) return 'yesterday';
|
|
107
|
+
if (diffDays < 7) return `${diffDays} days ago`;
|
|
108
|
+
if (diffDays < 30) return `${Math.floor(diffDays / 7)} week${Math.floor(diffDays / 7) > 1 ? 's' : ''} ago`;
|
|
109
|
+
if (diffDays < 365) return `${Math.floor(diffDays / 30)} month${Math.floor(diffDays / 30) > 1 ? 's' : ''} ago`;
|
|
110
|
+
return `${Math.floor(diffDays / 365)} year${Math.floor(diffDays / 365) > 1 ? 's' : ''} ago`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Simulated share counts (in production, fetch from API)
|
|
114
|
+
function getShareCount(platform: string): string {
|
|
115
|
+
const counts: Record<string, number> = {
|
|
116
|
+
twitter: Math.floor(Math.random() * 200) + 50,
|
|
117
|
+
linkedin: Math.floor(Math.random() * 150) + 30,
|
|
118
|
+
hn: Math.floor(Math.random() * 100) + 20
|
|
119
|
+
};
|
|
120
|
+
const count = counts[platform] || 0;
|
|
121
|
+
return count > 999 ? `${(count / 1000).toFixed(1)}k` : count.toString();
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function getTotalShares(): string {
|
|
125
|
+
const total =
|
|
126
|
+
Math.floor(Math.random() * 200) + 50 +
|
|
127
|
+
Math.floor(Math.random() * 150) + 30 +
|
|
128
|
+
Math.floor(Math.random() * 100) + 20;
|
|
129
|
+
return total > 999 ? `${(total / 1000).toFixed(1)}k` : total.toString();
|
|
130
|
+
}
|
|
131
|
+
</script>
|
|
132
|
+
|
|
133
|
+
<svelte:head>
|
|
134
|
+
<title>{post.title} | DocFetch Blog</title>
|
|
135
|
+
<meta name="description" content={post.excerpt} />
|
|
136
|
+
<meta name="keywords" content="convert documentation to markdown, LLM context, AI documentation, RAG preparation, markdown converter, DocFetch tutorial" />
|
|
137
|
+
|
|
138
|
+
<!-- Open Graph -->
|
|
139
|
+
<meta property="og:type" content="article" />
|
|
140
|
+
<meta property="og:title" content={post.title} />
|
|
141
|
+
<meta property="og:description" content="Complete guide to converting documentation websites into AI-ready markdown" />
|
|
142
|
+
<meta property="og:published_time" content={post.date} />
|
|
143
|
+
<meta property="article:author" content={post.author} />
|
|
144
|
+
<meta property="article:tag" content={post.tags.join(',')} />
|
|
145
|
+
|
|
146
|
+
<!-- Twitter Card -->
|
|
147
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
148
|
+
<meta name="twitter:title" content={post.title} />
|
|
149
|
+
<meta name="twitter:description" content="Step-by-step guide with code examples and best practices" />
|
|
150
|
+
|
|
151
|
+
<!-- Structured Data: BlogPosting Schema -->
|
|
152
|
+
<script type="application/ld+json">
|
|
153
|
+
{
|
|
154
|
+
"@context": "https://schema.org",
|
|
155
|
+
"@type": "BlogPosting",
|
|
156
|
+
"headline": {post.title},
|
|
157
|
+
"description": "{post.excerpt}",
|
|
158
|
+
"url": "{canonicalUrl}",
|
|
159
|
+
"author": {
|
|
160
|
+
"@type": "Person",
|
|
161
|
+
"name": {post.author},
|
|
162
|
+
"url": "https://github.com/AlphaTechini"
|
|
163
|
+
},
|
|
164
|
+
"datePublished": "{post.date}",
|
|
165
|
+
"dateModified": "{post.modifiedDate || post.date}",
|
|
166
|
+
"publisher": {
|
|
167
|
+
"@type": "Organization",
|
|
168
|
+
"name": "DocFetch",
|
|
169
|
+
"logo": {
|
|
170
|
+
"@type": "ImageObject",
|
|
171
|
+
"url": "{baseUrl}/favicon.svg"
|
|
172
|
+
}
|
|
173
|
+
},
|
|
174
|
+
"mainEntityOfPage": {
|
|
175
|
+
"@type": "WebPage",
|
|
176
|
+
"@id": canonicalUrl
|
|
177
|
+
},
|
|
178
|
+
"articleBody": "Complete guide to converting documentation websites into AI-ready markdown with LLM.txt indexing",
|
|
179
|
+
"wordCount": 3500,
|
|
180
|
+
"inLanguage": "en-US",
|
|
181
|
+
"keywords": {post.tags.join(', ')},
|
|
182
|
+
"articleSection": {post.category || 'Tutorial'}
|
|
183
|
+
}
|
|
184
|
+
</script>
|
|
185
|
+
|
|
186
|
+
<!-- Structured Data: FAQPage Schema (for People Also Ask) -->
|
|
187
|
+
<script type="application/ld+json">
|
|
188
|
+
{
|
|
189
|
+
"@context": "https://schema.org",
|
|
190
|
+
"@type": "FAQPage",
|
|
191
|
+
"mainEntity": {post.faqs.map(faq => ({
|
|
192
|
+
"@type": "Question",
|
|
193
|
+
"name": faq.question,
|
|
194
|
+
"acceptedAnswer": {
|
|
195
|
+
"@type": "Answer",
|
|
196
|
+
"text": faq.answer
|
|
197
|
+
}
|
|
198
|
+
}))}
|
|
199
|
+
}
|
|
200
|
+
</script>
|
|
201
|
+
</svelte:head>
|
|
202
|
+
|
|
203
|
+
<div class="container">
|
|
204
|
+
<ReadingProgress />
|
|
205
|
+
|
|
206
|
+
<header>
|
|
207
|
+
<nav>
|
|
208
|
+
<div class="logo">
|
|
209
|
+
<a href="/">
|
|
210
|
+
<span class="logo-icon">📚</span>
|
|
211
|
+
<span class="logo-text">DocFetch</span>
|
|
212
|
+
</a>
|
|
213
|
+
</div>
|
|
214
|
+
<div class="nav-links">
|
|
215
|
+
<a href="/#features">Features</a>
|
|
216
|
+
<a href="/#installation">Installation</a>
|
|
217
|
+
<a href="/blog" class="active">Blog</a>
|
|
218
|
+
<a href="https://github.com/AlphaTechini/doc-fetch" target="_blank" rel="noopener noreferrer">GitHub →</a>
|
|
219
|
+
</div>
|
|
220
|
+
</nav>
|
|
221
|
+
</header>
|
|
222
|
+
|
|
223
|
+
<div class="post-layout">
|
|
224
|
+
<main class="post-content">
|
|
225
|
+
<article class="post">
|
|
226
|
+
<header class="post-header">
|
|
227
|
+
<div class="breadcrumbs">
|
|
228
|
+
<a href="/blog">Blog</a>
|
|
229
|
+
<span>/</span>
|
|
230
|
+
<span>{post.title}</span>
|
|
231
|
+
</div>
|
|
232
|
+
|
|
233
|
+
<h1>{post.title}</h1>
|
|
234
|
+
|
|
235
|
+
<div class="meta">
|
|
236
|
+
<time datetime={post.date}>{post.date}</time>
|
|
237
|
+
<span class="separator">•</span>
|
|
238
|
+
<span class="author">{post.author}</span>
|
|
239
|
+
<span class="separator">•</span>
|
|
240
|
+
<span class="read-time">
|
|
241
|
+
<span class="read-time-icon">
|
|
242
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
243
|
+
<circle cx="12" cy="12" r="10"></circle>
|
|
244
|
+
<polyline points="12 6 12 12 16 14"></polyline>
|
|
245
|
+
</svg>
|
|
246
|
+
</span>
|
|
247
|
+
<span class="read-time-text">{animatedReadTime}</span>
|
|
248
|
+
</span>
|
|
249
|
+
{#if post.modifiedDate && post.modifiedDate !== post.date}
|
|
250
|
+
<span class="separator">•</span>
|
|
251
|
+
<span class="updated-badge" title="Last updated">
|
|
252
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
253
|
+
<polyline points="23 4 23 10 17 10"></polyline>
|
|
254
|
+
<path d="M20.49 15a9 9 0 1 1-2.12-9.36L23 10"></path>
|
|
255
|
+
</svg>
|
|
256
|
+
Updated {getRelativeTime(post.modifiedDate)}
|
|
257
|
+
</span>
|
|
258
|
+
{/if}
|
|
259
|
+
</div>
|
|
260
|
+
|
|
261
|
+
<div class="tags">
|
|
262
|
+
{#each post.tags as tag}
|
|
263
|
+
<span class="tag">{tag}</span>
|
|
264
|
+
{/each}
|
|
265
|
+
</div>
|
|
266
|
+
</header>
|
|
267
|
+
|
|
268
|
+
<div class="content" use:addCopyButtons>
|
|
269
|
+
{@html htmlContent}
|
|
270
|
+
</div>
|
|
271
|
+
</article>
|
|
272
|
+
|
|
273
|
+
<footer class="post-footer">
|
|
274
|
+
<!-- Author Bio Box (E-E-A-T Signal) -->
|
|
275
|
+
<section class="author-bio">
|
|
276
|
+
<div class="author-avatar">
|
|
277
|
+
👨💻
|
|
278
|
+
</div>
|
|
279
|
+
<div class="author-info">
|
|
280
|
+
<h4>{post.author}</h4>
|
|
281
|
+
<p class="author-role">Senior Infrastructure Engineer</p>
|
|
282
|
+
<p class="author-desc">
|
|
283
|
+
Specializing in Web2 + Web3 systems, AI orchestration, and distributed automation.
|
|
284
|
+
Building developer tools that reduce friction and increase leverage.
|
|
285
|
+
</p>
|
|
286
|
+
<div class="author-links">
|
|
287
|
+
<a href="https://github.com/AlphaTechini" target="_blank" rel="noopener noreferrer" class="author-link">
|
|
288
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
|
|
289
|
+
<path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/>
|
|
290
|
+
</svg>
|
|
291
|
+
GitHub
|
|
292
|
+
</a>
|
|
293
|
+
<a href="https://www.npmjs.com/~alphatechini" target="_blank" rel="noopener noreferrer" class="author-link">
|
|
294
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor">
|
|
295
|
+
<path d="M1.763 0C.786 0 0 .786 0 1.763v20.474C0 23.214.786 24 1.763 24h20.474c.977 0 1.763-.786 1.763-1.763V1.763C24 .786 23.214 0 22.237 0zM5.13 5.323l1.836-.017.016 13.472H5.146zm5.092 0h1.82v9.02h3.669V5.323h1.837v10.86h-9.163zm8.963 0h1.836v13.472h-1.836z"/>
|
|
296
|
+
</svg>
|
|
297
|
+
NPM
|
|
298
|
+
</a>
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
</section>
|
|
302
|
+
|
|
303
|
+
<!-- Related Posts with Thumbnails -->
|
|
304
|
+
<RelatedPosts
|
|
305
|
+
posts={post.relatedPosts?.map(slug => ({
|
|
306
|
+
slug,
|
|
307
|
+
title: getRelatedPostTitle(slug),
|
|
308
|
+
excerpt: getRelatedPostExcerpt(slug),
|
|
309
|
+
readTime: '8 min read'
|
|
310
|
+
})) || []}
|
|
311
|
+
/>
|
|
312
|
+
|
|
313
|
+
<div class="cta-box">
|
|
314
|
+
<h3>Ready to Convert Your Documentation?</h3>
|
|
315
|
+
<p>DocFetch automates the entire process. One command, complete docs, AI-ready output.</p>
|
|
316
|
+
<div class="cta-buttons">
|
|
317
|
+
<a href="/#installation" class="btn primary">Install DocFetch</a>
|
|
318
|
+
<a href="https://github.com/AlphaTechini/doc-fetch" target="_blank" rel="noopener noreferrer" class="btn secondary">View on GitHub</a>
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
|
|
322
|
+
<div class="share-section">
|
|
323
|
+
<h4>Share this article</h4>
|
|
324
|
+
<div class="share-buttons">
|
|
325
|
+
<a href="https://twitter.com/intent/tweet?text={encodeURIComponent(post.title)}&url={encodeURIComponent(canonicalUrl)}" target="_blank" rel="noopener noreferrer" class="share-btn twitter">
|
|
326
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/></svg>
|
|
327
|
+
Twitter
|
|
328
|
+
<span class="share-count">{getShareCount('twitter')}</span>
|
|
329
|
+
</a>
|
|
330
|
+
<a href="https://www.linkedin.com/sharing/share-offsite/?url={encodeURIComponent(canonicalUrl)}" target="_blank" rel="noopener noreferrer" class="share-btn linkedin">
|
|
331
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M4.98 3.5c0 1.381-1.11 2.5-2.48 2.5s-2.48-1.119-2.48-2.5c0-1.38 1.11-2.5 2.48-2.5s2.48 1.12 2.48 2.5zm.02 4.5h-5v16h5v-16zm7.982 0h-4.968v16h4.969v-8.399c0-4.67 6.029-5.052 6.029 0v8.399h4.988v-10.131c0-7.88-8.922-7.593-11.018-3.714v-2.155z"/></svg>
|
|
332
|
+
LinkedIn
|
|
333
|
+
<span class="share-count">{getShareCount('linkedin')}</span>
|
|
334
|
+
</a>
|
|
335
|
+
<a href="https://news.ycombinator.com/submitlink?u={encodeURIComponent(canonicalUrl)}&t={encodeURIComponent(post.title)}" target="_blank" rel="noopener noreferrer" class="share-btn hn">
|
|
336
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="currentColor"><path d="M2 2h20v20H2V2zm10.994 13.023l4.933-9.023h-2.229l-3.765 7.535L8.152 6H5.924l4.936 9.023h2.134z"/></svg>
|
|
337
|
+
Hacker News
|
|
338
|
+
<span class="share-count">{getShareCount('hn')}</span>
|
|
339
|
+
</a>
|
|
340
|
+
</div>
|
|
341
|
+
<p class="share-note">Join {getTotalShares()} developers who shared this article</p>
|
|
342
|
+
</div>
|
|
343
|
+
</footer>
|
|
344
|
+
</main>
|
|
345
|
+
|
|
346
|
+
<aside class="post-sidebar">
|
|
347
|
+
<TableOfContents contentSelector=".content" title="On this page" />
|
|
348
|
+
</aside>
|
|
349
|
+
</div>
|
|
350
|
+
|
|
351
|
+
<footer class="site-footer">
|
|
352
|
+
<div class="footer-content">
|
|
353
|
+
<div class="footer-left">
|
|
354
|
+
<p>Built with ❤️ for AI developers who deserve better documentation access</p>
|
|
355
|
+
<p class="copyright">© 2026 AlphaTechini. MIT License.</p>
|
|
356
|
+
</div>
|
|
357
|
+
<div class="footer-right">
|
|
358
|
+
<a href="https://github.com/AlphaTechini/doc-fetch" target="_blank" rel="noopener noreferrer">GitHub</a>
|
|
359
|
+
<a href="/blog">Blog</a>
|
|
360
|
+
<a href="https://www.npmjs.com/package/doc-fetch" target="_blank" rel="noopener noreferrer">NPM</a>
|
|
361
|
+
</div>
|
|
362
|
+
</div>
|
|
363
|
+
</footer>
|
|
364
|
+
</div>
|
|
365
|
+
|
|
366
|
+
<style>
|
|
367
|
+
:global(:root) {
|
|
368
|
+
--bg-primary: #ffffff;
|
|
369
|
+
--bg-secondary: #f8f9fa;
|
|
370
|
+
--text-primary: #1a1a1a;
|
|
371
|
+
--text-secondary: #4a4a4a;
|
|
372
|
+
--text-muted: #6b7280;
|
|
373
|
+
--accent: #0066cc;
|
|
374
|
+
--accent-hover: #0052a3;
|
|
375
|
+
--border: #e5e7eb;
|
|
376
|
+
--max-width: 800px;
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
:global(body) {
|
|
380
|
+
margin: 0;
|
|
381
|
+
padding: 0;
|
|
382
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
383
|
+
background: var(--bg-primary);
|
|
384
|
+
color: var(--text-primary);
|
|
385
|
+
line-height: 1.7;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
.container {
|
|
389
|
+
max-width: 1200px;
|
|
390
|
+
margin: 0 auto;
|
|
391
|
+
padding: 0 2rem;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
header {
|
|
395
|
+
position: fixed;
|
|
396
|
+
top: 0;
|
|
397
|
+
left: 0;
|
|
398
|
+
right: 0;
|
|
399
|
+
background: rgba(255, 255, 255, 0.95);
|
|
400
|
+
backdrop-filter: blur(10px);
|
|
401
|
+
border-bottom: 1px solid var(--border);
|
|
402
|
+
z-index: 1000;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
nav {
|
|
406
|
+
display: flex;
|
|
407
|
+
justify-content: space-between;
|
|
408
|
+
align-items: center;
|
|
409
|
+
padding: 1rem 2rem;
|
|
410
|
+
max-width: 1200px;
|
|
411
|
+
margin: 0 auto;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
.logo a {
|
|
415
|
+
display: flex;
|
|
416
|
+
align-items: center;
|
|
417
|
+
gap: 0.5rem;
|
|
418
|
+
font-weight: 700;
|
|
419
|
+
font-size: 1.25rem;
|
|
420
|
+
text-decoration: none;
|
|
421
|
+
color: var(--text-primary);
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
.logo-icon {
|
|
425
|
+
font-size: 1.5rem;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.nav-links {
|
|
429
|
+
display: flex;
|
|
430
|
+
gap: 2rem;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.nav-links a {
|
|
434
|
+
color: var(--text-secondary);
|
|
435
|
+
text-decoration: none;
|
|
436
|
+
font-size: 0.95rem;
|
|
437
|
+
transition: color 0.2s;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.nav-links a:hover,
|
|
441
|
+
.nav-links a.active {
|
|
442
|
+
color: var(--accent);
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.post-layout {
|
|
446
|
+
display: grid;
|
|
447
|
+
grid-template-columns: 1fr 280px;
|
|
448
|
+
gap: 3rem;
|
|
449
|
+
padding: 8rem 0 4rem;
|
|
450
|
+
max-width: 1200px;
|
|
451
|
+
margin: 0 auto;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
.post-content {
|
|
455
|
+
min-width: 0;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
.post-sidebar {
|
|
459
|
+
position: relative;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
.post {
|
|
463
|
+
margin-bottom: 3rem;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
.post-header {
|
|
467
|
+
margin-bottom: 3rem;
|
|
468
|
+
padding-bottom: 2rem;
|
|
469
|
+
border-bottom: 1px solid var(--border);
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.breadcrumbs {
|
|
473
|
+
font-size: 0.875rem;
|
|
474
|
+
color: var(--text-muted);
|
|
475
|
+
margin-bottom: 1.5rem;
|
|
476
|
+
}
|
|
477
|
+
|
|
478
|
+
.breadcrumbs a {
|
|
479
|
+
color: var(--text-muted);
|
|
480
|
+
text-decoration: none;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
.breadcrumbs a:hover {
|
|
484
|
+
color: var(--accent);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
h1 {
|
|
488
|
+
font-size: 2.5rem;
|
|
489
|
+
font-weight: 800;
|
|
490
|
+
line-height: 1.2;
|
|
491
|
+
margin: 0 0 1.5rem;
|
|
492
|
+
letter-spacing: -0.01em;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
.meta {
|
|
496
|
+
display: flex;
|
|
497
|
+
gap: 0.5rem;
|
|
498
|
+
align-items: center;
|
|
499
|
+
font-size: 0.95rem;
|
|
500
|
+
color: var(--text-muted);
|
|
501
|
+
margin-bottom: 1.5rem;
|
|
502
|
+
flex-wrap: wrap;
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
.separator {
|
|
506
|
+
color: var(--border);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
.read-time {
|
|
510
|
+
display: inline-flex;
|
|
511
|
+
align-items: center;
|
|
512
|
+
gap: 0.375rem;
|
|
513
|
+
font-weight: 600;
|
|
514
|
+
color: var(--accent);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
.read-time-icon {
|
|
518
|
+
display: flex;
|
|
519
|
+
align-items: center;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
.updated-badge {
|
|
523
|
+
display: inline-flex;
|
|
524
|
+
align-items: center;
|
|
525
|
+
gap: 0.375rem;
|
|
526
|
+
background: rgba(39, 201, 63, 0.1);
|
|
527
|
+
color: #27c93f;
|
|
528
|
+
padding: 0.25rem 0.625rem;
|
|
529
|
+
border-radius: 12px;
|
|
530
|
+
font-size: 0.8rem;
|
|
531
|
+
font-weight: 600;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
.dark .updated-badge {
|
|
535
|
+
background: rgba(39, 201, 63, 0.15);
|
|
536
|
+
color: #3fb950;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
.tags {
|
|
540
|
+
display: flex;
|
|
541
|
+
gap: 0.5rem;
|
|
542
|
+
flex-wrap: wrap;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.tag {
|
|
546
|
+
background: rgba(0, 102, 204, 0.1);
|
|
547
|
+
color: var(--accent);
|
|
548
|
+
padding: 0.25rem 0.75rem;
|
|
549
|
+
border-radius: 12px;
|
|
550
|
+
font-size: 0.8rem;
|
|
551
|
+
font-weight: 500;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
.author-bio {
|
|
555
|
+
display: flex;
|
|
556
|
+
gap: 1.5rem;
|
|
557
|
+
background: var(--bg-secondary);
|
|
558
|
+
padding: 2rem;
|
|
559
|
+
border-radius: 8px;
|
|
560
|
+
margin-bottom: 3rem;
|
|
561
|
+
align-items: center;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
.author-avatar {
|
|
565
|
+
font-size: 4rem;
|
|
566
|
+
flex-shrink: 0;
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
.author-info h4 {
|
|
570
|
+
margin: 0 0 0.25rem;
|
|
571
|
+
font-size: 1.25rem;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
.author-role {
|
|
575
|
+
color: var(--accent);
|
|
576
|
+
font-weight: 600;
|
|
577
|
+
margin: 0 0 0.75rem;
|
|
578
|
+
font-size: 0.95rem;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
.author-desc {
|
|
582
|
+
color: var(--text-secondary);
|
|
583
|
+
margin: 0 0 1rem;
|
|
584
|
+
line-height: 1.6;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
.author-links {
|
|
588
|
+
display: flex;
|
|
589
|
+
gap: 1rem;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.author-link {
|
|
593
|
+
display: inline-flex;
|
|
594
|
+
align-items: center;
|
|
595
|
+
gap: 0.5rem;
|
|
596
|
+
color: var(--text-secondary);
|
|
597
|
+
text-decoration: none;
|
|
598
|
+
font-weight: 500;
|
|
599
|
+
transition: color 0.2s;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
.author-link:hover {
|
|
603
|
+
color: var(--accent);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.author-link svg {
|
|
607
|
+
width: 18px;
|
|
608
|
+
height: 18px;
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
.content {
|
|
612
|
+
font-size: 1.1875rem; /* 19px - improved readability */
|
|
613
|
+
line-height: 1.85; /* Better vertical rhythm */
|
|
614
|
+
max-width: 65ch; /* Optimal line length for reading */
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
.content h2 {
|
|
618
|
+
font-size: 1.875rem; /* 30px */
|
|
619
|
+
margin-top: 3.5rem;
|
|
620
|
+
margin-bottom: 1.5rem;
|
|
621
|
+
font-weight: 700;
|
|
622
|
+
letter-spacing: -0.01em;
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
.content h3 {
|
|
626
|
+
font-size: 1.5rem; /* 24px */
|
|
627
|
+
margin-top: 2.75rem;
|
|
628
|
+
margin-bottom: 1.25rem;
|
|
629
|
+
font-weight: 600;
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
.content h4 {
|
|
633
|
+
font-size: 1.25rem;
|
|
634
|
+
margin-top: 2rem;
|
|
635
|
+
margin-bottom: 1rem;
|
|
636
|
+
font-weight: 600;
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
.content p {
|
|
640
|
+
margin-bottom: 1.75rem; /* More breathing room */
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
.content ul, .content ol {
|
|
644
|
+
margin-bottom: 1.75rem;
|
|
645
|
+
padding-left: 2rem;
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
.content li {
|
|
649
|
+
margin-bottom: 0.875rem; /* Better spacing between items */
|
|
650
|
+
line-height: 1.7;
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
.content pre {
|
|
654
|
+
background: #1e1e1e;
|
|
655
|
+
color: #d4d4d4;
|
|
656
|
+
padding: 1.5rem;
|
|
657
|
+
border-radius: 6px;
|
|
658
|
+
overflow-x: auto;
|
|
659
|
+
margin: 1.5rem 0;
|
|
660
|
+
font-size: 0.9rem;
|
|
661
|
+
line-height: 1.6;
|
|
662
|
+
position: relative;
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
.content code {
|
|
666
|
+
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
667
|
+
color: #d4d4d4;
|
|
668
|
+
}
|
|
669
|
+
|
|
670
|
+
.content pre code {
|
|
671
|
+
color: #d4d4d4;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
.copy-code-button {
|
|
675
|
+
position: absolute;
|
|
676
|
+
top: 0.75rem;
|
|
677
|
+
right: 0.75rem;
|
|
678
|
+
background: rgba(255, 255, 255, 0.1);
|
|
679
|
+
border: none;
|
|
680
|
+
border-radius: 4px;
|
|
681
|
+
padding: 0.5rem;
|
|
682
|
+
cursor: pointer;
|
|
683
|
+
color: #d4d4d4;
|
|
684
|
+
transition: all 0.2s;
|
|
685
|
+
opacity: 0;
|
|
686
|
+
z-index: 10;
|
|
687
|
+
display: flex;
|
|
688
|
+
align-items: center;
|
|
689
|
+
gap: 0.5rem;
|
|
690
|
+
font-size: 0.875rem;
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
.copy-code-button:hover,
|
|
694
|
+
pre:hover .copy-code-button {
|
|
695
|
+
opacity: 1;
|
|
696
|
+
background: rgba(255, 255, 255, 0.15);
|
|
697
|
+
}
|
|
698
|
+
|
|
699
|
+
.copy-code-button:active {
|
|
700
|
+
transform: scale(0.95);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
.copy-code-button.copied {
|
|
704
|
+
background: rgba(39, 201, 63, 0.2);
|
|
705
|
+
}
|
|
706
|
+
|
|
707
|
+
.copy-code-button svg {
|
|
708
|
+
display: block;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
.copy-code-button .tooltip {
|
|
712
|
+
background: rgba(0, 0, 0, 0.8);
|
|
713
|
+
color: white;
|
|
714
|
+
padding: 0.25rem 0.5rem;
|
|
715
|
+
border-radius: 4px;
|
|
716
|
+
font-size: 0.75rem;
|
|
717
|
+
white-space: nowrap;
|
|
718
|
+
pointer-events: none;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
.content :global(code:not(pre code)) {
|
|
722
|
+
background: var(--bg-secondary);
|
|
723
|
+
padding: 0.2rem 0.5rem;
|
|
724
|
+
border-radius: 3px;
|
|
725
|
+
font-size: 0.9em;
|
|
726
|
+
color: var(--text-primary);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
.content ul, .content ol {
|
|
730
|
+
margin-bottom: 1.5rem;
|
|
731
|
+
padding-left: 2rem;
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
.content li {
|
|
735
|
+
margin-bottom: 0.75rem;
|
|
736
|
+
}
|
|
737
|
+
|
|
738
|
+
.content blockquote {
|
|
739
|
+
border-left: 3px solid var(--accent);
|
|
740
|
+
padding-left: 1.5rem;
|
|
741
|
+
margin: 1.5rem 0;
|
|
742
|
+
color: var(--text-secondary);
|
|
743
|
+
font-style: italic;
|
|
744
|
+
}
|
|
745
|
+
|
|
746
|
+
.content hr {
|
|
747
|
+
border: none;
|
|
748
|
+
border-top: 1px solid var(--border);
|
|
749
|
+
margin: 3rem 0;
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
.post-footer {
|
|
753
|
+
margin-top: 4rem;
|
|
754
|
+
padding-top: 3rem;
|
|
755
|
+
border-top: 1px solid var(--border);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
.related-posts {
|
|
759
|
+
margin-bottom: 3rem;
|
|
760
|
+
padding-bottom: 2rem;
|
|
761
|
+
border-bottom: 1px solid var(--border);
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
.related-posts h3 {
|
|
765
|
+
font-size: 1.4rem;
|
|
766
|
+
margin-bottom: 1.5rem;
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
.related-grid {
|
|
770
|
+
display: grid;
|
|
771
|
+
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
|
772
|
+
gap: 1.5rem;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
.related-card {
|
|
776
|
+
background: var(--bg-secondary);
|
|
777
|
+
padding: 1.5rem;
|
|
778
|
+
border-radius: 6px;
|
|
779
|
+
transition: transform 0.2s;
|
|
780
|
+
}
|
|
781
|
+
|
|
782
|
+
.related-card:hover {
|
|
783
|
+
transform: translateY(-2px);
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
.related-card h4 {
|
|
787
|
+
font-size: 1.1rem;
|
|
788
|
+
margin: 0 0 0.75rem;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
.related-card h4 a {
|
|
792
|
+
color: var(--text-primary);
|
|
793
|
+
text-decoration: none;
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
.related-card h4 a:hover {
|
|
797
|
+
color: var(--accent);
|
|
798
|
+
}
|
|
799
|
+
|
|
800
|
+
.related-card p {
|
|
801
|
+
font-size: 0.9rem;
|
|
802
|
+
color: var(--text-secondary);
|
|
803
|
+
margin: 0;
|
|
804
|
+
line-height: 1.6;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
.cta-box {
|
|
808
|
+
background: var(--bg-secondary);
|
|
809
|
+
padding: 2.5rem;
|
|
810
|
+
border-radius: 8px;
|
|
811
|
+
text-align: center;
|
|
812
|
+
margin-bottom: 3rem;
|
|
813
|
+
}
|
|
814
|
+
|
|
815
|
+
.cta-box h3 {
|
|
816
|
+
margin: 0 0 1rem;
|
|
817
|
+
font-size: 1.5rem;
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
.cta-box p {
|
|
821
|
+
color: var(--text-secondary);
|
|
822
|
+
margin: 0 0 2rem;
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
.cta-buttons {
|
|
826
|
+
display: flex;
|
|
827
|
+
gap: 1rem;
|
|
828
|
+
justify-content: center;
|
|
829
|
+
}
|
|
830
|
+
|
|
831
|
+
.btn {
|
|
832
|
+
display: inline-block;
|
|
833
|
+
padding: 0.875rem 2rem;
|
|
834
|
+
border-radius: 6px;
|
|
835
|
+
font-weight: 600;
|
|
836
|
+
text-decoration: none;
|
|
837
|
+
transition: all 0.2s;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
.btn.primary {
|
|
841
|
+
background: var(--accent);
|
|
842
|
+
color: white;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
.btn.primary:hover {
|
|
846
|
+
background: var(--accent-hover);
|
|
847
|
+
}
|
|
848
|
+
|
|
849
|
+
.btn.secondary {
|
|
850
|
+
background: transparent;
|
|
851
|
+
color: var(--text-secondary);
|
|
852
|
+
border: 1px solid var(--border);
|
|
853
|
+
}
|
|
854
|
+
|
|
855
|
+
.btn.secondary:hover {
|
|
856
|
+
border-color: var(--text-secondary);
|
|
857
|
+
}
|
|
858
|
+
|
|
859
|
+
.share-section h4 {
|
|
860
|
+
margin: 0 0 1rem;
|
|
861
|
+
font-size: 1.1rem;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.share-buttons {
|
|
865
|
+
display: flex;
|
|
866
|
+
gap: 1rem;
|
|
867
|
+
flex-wrap: wrap;
|
|
868
|
+
}
|
|
869
|
+
|
|
870
|
+
.share-btn {
|
|
871
|
+
display: inline-flex;
|
|
872
|
+
align-items: center;
|
|
873
|
+
gap: 0.5rem;
|
|
874
|
+
padding: 0.625rem 1.25rem;
|
|
875
|
+
border-radius: 6px;
|
|
876
|
+
text-decoration: none;
|
|
877
|
+
font-weight: 500;
|
|
878
|
+
font-size: 0.9rem;
|
|
879
|
+
transition: all 0.2s;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
.share-btn.twitter {
|
|
883
|
+
background: #1DA1F2;
|
|
884
|
+
color: white;
|
|
885
|
+
}
|
|
886
|
+
|
|
887
|
+
.share-btn.linkedin {
|
|
888
|
+
background: #0077B5;
|
|
889
|
+
color: white;
|
|
890
|
+
}
|
|
891
|
+
|
|
892
|
+
.share-btn.hn {
|
|
893
|
+
background: #FF6600;
|
|
894
|
+
color: white;
|
|
895
|
+
}
|
|
896
|
+
|
|
897
|
+
.share-btn:hover {
|
|
898
|
+
opacity: 0.9;
|
|
899
|
+
transform: translateY(-2px);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
.share-btn svg {
|
|
903
|
+
flex-shrink: 0;
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.share-count {
|
|
907
|
+
background: rgba(255, 255, 255, 0.2);
|
|
908
|
+
padding: 0.125rem 0.5rem;
|
|
909
|
+
border-radius: 12px;
|
|
910
|
+
font-size: 0.75rem;
|
|
911
|
+
font-weight: 600;
|
|
912
|
+
margin-left: 0.25rem;
|
|
913
|
+
}
|
|
914
|
+
|
|
915
|
+
.share-note {
|
|
916
|
+
margin-top: 1rem;
|
|
917
|
+
font-size: 0.875rem;
|
|
918
|
+
color: var(--text-muted);
|
|
919
|
+
text-align: center;
|
|
920
|
+
}
|
|
921
|
+
|
|
922
|
+
.site-footer {
|
|
923
|
+
border-top: 1px solid var(--border);
|
|
924
|
+
padding: 3rem 0;
|
|
925
|
+
margin-top: 4rem;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
.footer-content {
|
|
929
|
+
display: flex;
|
|
930
|
+
justify-content: space-between;
|
|
931
|
+
align-items: center;
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
.footer-left p {
|
|
935
|
+
margin: 0;
|
|
936
|
+
color: var(--text-secondary);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
.copyright {
|
|
940
|
+
font-size: 0.875rem;
|
|
941
|
+
margin-top: 0.5rem !important;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
.footer-right {
|
|
945
|
+
display: flex;
|
|
946
|
+
gap: 2rem;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
.footer-right a {
|
|
950
|
+
color: var(--text-secondary);
|
|
951
|
+
text-decoration: none;
|
|
952
|
+
transition: color 0.2s;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
.footer-right a:hover {
|
|
956
|
+
color: var(--accent);
|
|
957
|
+
}
|
|
958
|
+
|
|
959
|
+
@media (max-width: 1200px) {
|
|
960
|
+
.post-layout {
|
|
961
|
+
grid-template-columns: 1fr;
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
.post-sidebar {
|
|
965
|
+
display: none;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
|
|
969
|
+
@media (max-width: 768px) {
|
|
970
|
+
h1 {
|
|
971
|
+
font-size: 2rem;
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
.content {
|
|
975
|
+
font-size: 1rem;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
.cta-buttons {
|
|
979
|
+
flex-direction: column;
|
|
980
|
+
}
|
|
981
|
+
|
|
982
|
+
.footer-content {
|
|
983
|
+
flex-direction: column;
|
|
984
|
+
gap: 2rem;
|
|
985
|
+
text-align: center;
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
</style>
|