@aureuma/svelta 0.0.1
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/.changeset/README.md +8 -0
- package/.changeset/config.json +14 -0
- package/.changeset/publish-blogkit.md +5 -0
- package/.github/workflows/release.yml +65 -0
- package/LICENSE +22 -0
- package/README.md +35 -0
- package/docs/mintlify-blog-study.md +697 -0
- package/package.json +59 -0
- package/packages/blogkit/CHANGELOG.md +6 -0
- package/packages/blogkit/LICENSE +22 -0
- package/packages/blogkit/README.md +93 -0
- package/packages/blogkit/dist/components/blog/Avatar.svelte +15 -0
- package/packages/blogkit/dist/components/blog/Avatar.svelte.d.ts +22 -0
- package/packages/blogkit/dist/components/blog/BackLink.svelte +23 -0
- package/packages/blogkit/dist/components/blog/BackLink.svelte.d.ts +21 -0
- package/packages/blogkit/dist/components/blog/BlogCard.svelte +37 -0
- package/packages/blogkit/dist/components/blog/BlogCard.svelte.d.ts +22 -0
- package/packages/blogkit/dist/components/blog/BlogHeroCard.svelte +36 -0
- package/packages/blogkit/dist/components/blog/BlogHeroCard.svelte.d.ts +21 -0
- package/packages/blogkit/dist/components/blog/Container.svelte +8 -0
- package/packages/blogkit/dist/components/blog/Container.svelte.d.ts +29 -0
- package/packages/blogkit/dist/components/blog/ImageLightbox.svelte +58 -0
- package/packages/blogkit/dist/components/blog/ImageLightbox.svelte.d.ts +24 -0
- package/packages/blogkit/dist/components/blog/MorePosts.svelte +15 -0
- package/packages/blogkit/dist/components/blog/MorePosts.svelte.d.ts +21 -0
- package/packages/blogkit/dist/components/blog/ShareButtons.svelte +113 -0
- package/packages/blogkit/dist/components/blog/ShareButtons.svelte.d.ts +23 -0
- package/packages/blogkit/dist/components/blog/SummaryCard.svelte +11 -0
- package/packages/blogkit/dist/components/blog/SummaryCard.svelte.d.ts +20 -0
- package/packages/blogkit/dist/components/blog/TagTabs.svelte +32 -0
- package/packages/blogkit/dist/components/blog/TagTabs.svelte.d.ts +23 -0
- package/packages/blogkit/dist/index.d.ts +11 -0
- package/packages/blogkit/dist/index.js +11 -0
- package/packages/blogkit/dist/server/blog.d.ts +39 -0
- package/packages/blogkit/dist/server/blog.js +222 -0
- package/packages/blogkit/dist/server/index.d.ts +1 -0
- package/packages/blogkit/dist/server/index.js +1 -0
- package/packages/blogkit/dist/theme/ThemeSwitcher.svelte +34 -0
- package/packages/blogkit/dist/theme/ThemeSwitcher.svelte.d.ts +21 -0
- package/packages/blogkit/dist/theme/index.d.ts +2 -0
- package/packages/blogkit/dist/theme/index.js +2 -0
- package/packages/blogkit/dist/theme/store.d.ts +12 -0
- package/packages/blogkit/dist/theme/store.js +50 -0
- package/packages/blogkit/dist/types/blog.d.ts +31 -0
- package/packages/blogkit/dist/types/blog.js +1 -0
- package/packages/blogkit/package.json +66 -0
- package/packages/blogkit/src/lib/components/blog/Avatar.svelte +15 -0
- package/packages/blogkit/src/lib/components/blog/BackLink.svelte +23 -0
- package/packages/blogkit/src/lib/components/blog/BlogCard.svelte +37 -0
- package/packages/blogkit/src/lib/components/blog/BlogHeroCard.svelte +36 -0
- package/packages/blogkit/src/lib/components/blog/Container.svelte +8 -0
- package/packages/blogkit/src/lib/components/blog/ImageLightbox.svelte +58 -0
- package/packages/blogkit/src/lib/components/blog/MorePosts.svelte +15 -0
- package/packages/blogkit/src/lib/components/blog/ShareButtons.svelte +113 -0
- package/packages/blogkit/src/lib/components/blog/SummaryCard.svelte +11 -0
- package/packages/blogkit/src/lib/components/blog/TagTabs.svelte +32 -0
- package/packages/blogkit/src/lib/index.ts +15 -0
- package/packages/blogkit/src/lib/server/blog.ts +264 -0
- package/packages/blogkit/src/lib/server/index.ts +2 -0
- package/packages/blogkit/src/lib/theme/ThemeSwitcher.svelte +34 -0
- package/packages/blogkit/src/lib/theme/index.ts +3 -0
- package/packages/blogkit/src/lib/theme/store.ts +64 -0
- package/packages/blogkit/src/lib/types/blog.ts +36 -0
- package/packages/blogkit/svelte.config.js +8 -0
- package/packages/blogkit/tsconfig.json +5 -0
- package/playwright.config.ts +24 -0
- package/postcss.config.cjs +6 -0
- package/src/app.css +146 -0
- package/src/app.d.ts +13 -0
- package/src/app.html +26 -0
- package/src/content/blog/ai-summary-cards-with-frontmatter.md +32 -0
- package/src/content/blog/announcing-svelta-blog.md +19 -0
- package/src/content/blog/best-practices-ship-with-checklists.md +26 -0
- package/src/content/blog/building-a-mintlify-inspired-blog.md +49 -0
- package/src/content/blog/design-tokens-that-scale.md +47 -0
- package/src/content/blog/for-founders-why-speed-matters.md +23 -0
- package/src/content/blog/infinite-scroll-with-intersection-observer.md +37 -0
- package/src/content/blog/markdown-kitchen-sink.md +101 -0
- package/src/content/blog/markdown-pipeline-mdsvex-shiki.md +39 -0
- package/src/content/blog/rss-feeds-that-actually-work.md +25 -0
- package/src/content/blog/tag-tabs-and-mobile-fade-masks.md +25 -0
- package/src/lib/assets/favicon.svg +1 -0
- package/src/lib/components/site/SiteFooter.svelte +24 -0
- package/src/lib/components/site/SiteHeader.svelte +36 -0
- package/src/lib/content/authors.ts +28 -0
- package/src/lib/index.ts +1 -0
- package/src/lib/server/blog.ts +22 -0
- package/src/lib/server/rss.ts +58 -0
- package/src/lib/server/seo.ts +31 -0
- package/src/lib/stores/theme.ts +10 -0
- package/src/lib/types/blog.ts +1 -0
- package/src/routes/+layout.svelte +31 -0
- package/src/routes/+page.svelte +44 -0
- package/src/routes/blog/+page.server.ts +28 -0
- package/src/routes/blog/+page.svelte +122 -0
- package/src/routes/blog/[slug]/+page.server.ts +39 -0
- package/src/routes/blog/[slug]/+page.svelte +118 -0
- package/src/routes/blog/posts.json/+server.ts +32 -0
- package/src/routes/feed.xml/+server.ts +21 -0
- package/static/blog/authors/alex.svg +13 -0
- package/static/blog/authors/maria.svg +13 -0
- package/static/blog/authors/shawn.svg +13 -0
- package/static/blog/covers/ai-summary.svg +38 -0
- package/static/blog/covers/design-tokens.svg +37 -0
- package/static/blog/covers/infinite-scroll.svg +38 -0
- package/static/blog/covers/kitchen-sink.svg +36 -0
- package/static/blog/covers/markdown-pipeline.svg +41 -0
- package/static/blog/covers/mintlify-style.svg +35 -0
- package/static/blog/covers/rss.svg +34 -0
- package/static/robots.txt +3 -0
- package/svelte.config.js +70 -0
- package/tailwind.config.cjs +133 -0
- package/tests/blog.spec.ts +63 -0
- package/tsconfig.json +21 -0
- package/vite.config.ts +14 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { Avatar, BackLink, Container, ImageLightbox, MorePosts, ShareButtons, SummaryCard } from '@aureuma/blogkit';
|
|
3
|
+
import type { BlogPost } from '$lib/types/blog';
|
|
4
|
+
|
|
5
|
+
let { data } = $props<{
|
|
6
|
+
data: {
|
|
7
|
+
post: BlogPost;
|
|
8
|
+
contentHtml: string;
|
|
9
|
+
morePosts: BlogPost[];
|
|
10
|
+
canonicalUrl: string;
|
|
11
|
+
seo: {
|
|
12
|
+
title: string;
|
|
13
|
+
description: string;
|
|
14
|
+
canonicalUrl: string;
|
|
15
|
+
og: { title: string; description: string; type: 'article'; url: string };
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
}>();
|
|
19
|
+
|
|
20
|
+
let lightbox = $state<{ src: string; alt: string } | null>(null);
|
|
21
|
+
let articleEl = $state<HTMLElement | null>(null);
|
|
22
|
+
|
|
23
|
+
$effect(() => {
|
|
24
|
+
// Re-bind image zoom handlers when content changes (e.g. client-side navigation).
|
|
25
|
+
const _ = data.contentHtml;
|
|
26
|
+
if (!articleEl) return;
|
|
27
|
+
|
|
28
|
+
const imgs = Array.from(articleEl.querySelectorAll('img'));
|
|
29
|
+
const onClick = (e: Event) => {
|
|
30
|
+
const img = e.currentTarget as HTMLImageElement;
|
|
31
|
+
lightbox = { src: img.currentSrc || img.src, alt: img.alt || data.post.title };
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
for (const img of imgs) img.addEventListener('click', onClick);
|
|
35
|
+
return () => {
|
|
36
|
+
for (const img of imgs) img.removeEventListener('click', onClick);
|
|
37
|
+
};
|
|
38
|
+
});
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<svelte:head>
|
|
42
|
+
<title>{data.seo.title}</title>
|
|
43
|
+
<meta name="description" content={data.seo.description} />
|
|
44
|
+
<link rel="canonical" href={data.seo.canonicalUrl} />
|
|
45
|
+
<meta property="og:title" content={data.seo.og.title} />
|
|
46
|
+
<meta property="og:description" content={data.seo.og.description} />
|
|
47
|
+
<meta property="og:type" content={data.seo.og.type} />
|
|
48
|
+
<meta property="og:url" content={data.seo.og.url} />
|
|
49
|
+
</svelte:head>
|
|
50
|
+
|
|
51
|
+
<Container size="4xl">
|
|
52
|
+
<div class="mt-[4.5rem] pb-[7.5rem]">
|
|
53
|
+
<BackLink />
|
|
54
|
+
|
|
55
|
+
<header class="mt-8 border-b border-border-soft/10 pb-8">
|
|
56
|
+
<div class="flex items-center gap-2 text-xs font-mono uppercase tracking-[0.6px]">
|
|
57
|
+
<span class="text-brand">{data.post.category.label}</span>
|
|
58
|
+
<span class="text-text-muted" aria-hidden="true">/</span>
|
|
59
|
+
<span class="text-text-muted">{data.post.readingTimeLong}</span>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<h1 class="mt-4 text-4xl font-semibold leading-[44px] tracking-[-0.8px] text-text-main">
|
|
63
|
+
{data.post.title}
|
|
64
|
+
</h1>
|
|
65
|
+
|
|
66
|
+
<p class="mt-4 text-xs font-mono uppercase tracking-[0.6px] text-text-muted">
|
|
67
|
+
{data.post.dateLong}
|
|
68
|
+
</p>
|
|
69
|
+
</header>
|
|
70
|
+
|
|
71
|
+
<div class="mt-10 grid grid-cols-1 gap-x-16 md:grid-cols-[minmax(0,628px)_160px]">
|
|
72
|
+
<div class="min-w-0">
|
|
73
|
+
<div class="overflow-hidden rounded-3xl border border-border-soft/10 bg-background-soft">
|
|
74
|
+
<img src={data.post.cover} alt={data.post.title} class="h-[360px] w-full object-cover" />
|
|
75
|
+
</div>
|
|
76
|
+
|
|
77
|
+
{#if data.post.summaryAI}
|
|
78
|
+
<div class="mt-6">
|
|
79
|
+
<SummaryCard summary={data.post.summaryAI} />
|
|
80
|
+
</div>
|
|
81
|
+
{/if}
|
|
82
|
+
|
|
83
|
+
<div class="mt-8 flex flex-col gap-6 md:hidden">
|
|
84
|
+
<div class="flex items-center gap-3">
|
|
85
|
+
<Avatar src={data.post.author.avatar} alt={data.post.author.name} size={48} />
|
|
86
|
+
<div class="leading-tight">
|
|
87
|
+
<div class="text-sm font-medium tracking-tight text-text-main">
|
|
88
|
+
{data.post.author.name}
|
|
89
|
+
</div>
|
|
90
|
+
<div class="text-xs text-text-muted">{data.post.author.title}</div>
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
<ShareButtons title={data.post.title} url={data.canonicalUrl} testId="blog-share-mobile" />
|
|
94
|
+
</div>
|
|
95
|
+
|
|
96
|
+
<article bind:this={articleEl} class="blog-prose prose mt-10">
|
|
97
|
+
{@html data.contentHtml}
|
|
98
|
+
</article>
|
|
99
|
+
|
|
100
|
+
<MorePosts posts={data.morePosts} />
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<aside class="sticky top-20 hidden self-start md:flex md:flex-col md:gap-8">
|
|
104
|
+
<div class="flex items-center gap-3">
|
|
105
|
+
<Avatar src={data.post.author.avatar} alt={data.post.author.name} size={48} />
|
|
106
|
+
<div class="leading-tight">
|
|
107
|
+
<div class="text-sm font-medium tracking-tight text-text-main">{data.post.author.name}</div>
|
|
108
|
+
<div class="text-xs text-text-muted">{data.post.author.title}</div>
|
|
109
|
+
</div>
|
|
110
|
+
</div>
|
|
111
|
+
|
|
112
|
+
<ShareButtons title={data.post.title} url={data.canonicalUrl} testId="blog-share-desktop" />
|
|
113
|
+
</aside>
|
|
114
|
+
</div>
|
|
115
|
+
</div>
|
|
116
|
+
</Container>
|
|
117
|
+
|
|
118
|
+
<ImageLightbox image={lightbox} onClose={() => (lightbox = null)} />
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { getAllPosts, getCategories, pickHero } from '$lib/server/blog';
|
|
2
|
+
import { json } from '@sveltejs/kit';
|
|
3
|
+
import type { RequestHandler } from './$types';
|
|
4
|
+
|
|
5
|
+
const DEFAULT_LIMIT = 8;
|
|
6
|
+
const MAX_LIMIT = 24;
|
|
7
|
+
|
|
8
|
+
export const GET: RequestHandler = async ({ url }) => {
|
|
9
|
+
const offset = Math.max(0, Number.parseInt(url.searchParams.get('offset') ?? '0', 10) || 0);
|
|
10
|
+
const limitRaw =
|
|
11
|
+
Number.parseInt(url.searchParams.get('limit') ?? String(DEFAULT_LIMIT), 10) || DEFAULT_LIMIT;
|
|
12
|
+
const limit = Math.min(MAX_LIMIT, Math.max(1, limitRaw));
|
|
13
|
+
|
|
14
|
+
const [all, categories] = await Promise.all([getAllPosts(), getCategories()]);
|
|
15
|
+
const hero = await pickHero(all);
|
|
16
|
+
|
|
17
|
+
const requestedCategory = url.searchParams.get('category') ?? '';
|
|
18
|
+
const category =
|
|
19
|
+
requestedCategory && categories.some((c) => c.slug === requestedCategory)
|
|
20
|
+
? requestedCategory
|
|
21
|
+
: '';
|
|
22
|
+
|
|
23
|
+
const rest = all.filter((p) => p.slug !== hero.slug);
|
|
24
|
+
const filtered = category ? rest.filter((p) => p.category.slug === category) : rest;
|
|
25
|
+
const posts = filtered.slice(offset, offset + limit);
|
|
26
|
+
|
|
27
|
+
return json({
|
|
28
|
+
posts,
|
|
29
|
+
hasMore: filtered.length > offset + posts.length
|
|
30
|
+
});
|
|
31
|
+
};
|
|
32
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getAllPosts } from '$lib/server/blog';
|
|
2
|
+
import { buildRss } from '$lib/server/rss';
|
|
3
|
+
import type { RequestHandler } from './$types';
|
|
4
|
+
|
|
5
|
+
export const GET: RequestHandler = async ({ url }) => {
|
|
6
|
+
const posts = await getAllPosts();
|
|
7
|
+
|
|
8
|
+
const rss = buildRss({
|
|
9
|
+
baseUrl: url,
|
|
10
|
+
posts,
|
|
11
|
+
siteTitle: 'svelta Blog',
|
|
12
|
+
description: 'Engineering, design, and product notes from svelta.'
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
return new Response(rss, {
|
|
16
|
+
headers: {
|
|
17
|
+
'content-type': 'application/rss+xml; charset=utf-8',
|
|
18
|
+
'cache-control': 'max-age=0, s-maxage=3600'
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#fb7185"/>
|
|
5
|
+
<stop offset="1" stop-color="#f59e0b"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect width="128" height="128" rx="64" fill="url(#g)"/>
|
|
9
|
+
<circle cx="64" cy="58" r="22" fill="rgba(255,255,255,0.23)"/>
|
|
10
|
+
<path d="M26 116c10-22 26-32 38-32s28 10 38 32" fill="rgba(255,255,255,0.23)"/>
|
|
11
|
+
<text x="64" y="76" text-anchor="middle" font-family="Inter, Arial, sans-serif" font-size="28" font-weight="700" fill="rgba(255,255,255,0.92)">A</text>
|
|
12
|
+
</svg>
|
|
13
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#a78bfa"/>
|
|
5
|
+
<stop offset="1" stop-color="#22c55e"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect width="128" height="128" rx="64" fill="url(#g)"/>
|
|
9
|
+
<circle cx="64" cy="58" r="22" fill="rgba(255,255,255,0.23)"/>
|
|
10
|
+
<path d="M26 116c10-22 26-32 38-32s28 10 38 32" fill="rgba(255,255,255,0.23)"/>
|
|
11
|
+
<text x="64" y="76" text-anchor="middle" font-family="Inter, Arial, sans-serif" font-size="28" font-weight="700" fill="rgba(255,255,255,0.92)">M</text>
|
|
12
|
+
</svg>
|
|
13
|
+
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="g" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#22c55e"/>
|
|
5
|
+
<stop offset="1" stop-color="#0ea5e9"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
</defs>
|
|
8
|
+
<rect width="128" height="128" rx="64" fill="url(#g)"/>
|
|
9
|
+
<circle cx="64" cy="58" r="22" fill="rgba(255,255,255,0.25)"/>
|
|
10
|
+
<path d="M26 116c10-22 26-32 38-32s28 10 38 32" fill="rgba(255,255,255,0.25)"/>
|
|
11
|
+
<text x="64" y="76" text-anchor="middle" font-family="Inter, Arial, sans-serif" font-size="28" font-weight="700" fill="rgba(255,255,255,0.92)">S</text>
|
|
12
|
+
</svg>
|
|
13
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#0b1220"/>
|
|
5
|
+
<stop offset="1" stop-color="#111827"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<radialGradient id="g1" cx="50%" cy="40%" r="60%">
|
|
8
|
+
<stop offset="0" stop-color="rgba(167,139,250,0.50)"/>
|
|
9
|
+
<stop offset="1" stop-color="rgba(167,139,250,0)"/>
|
|
10
|
+
</radialGradient>
|
|
11
|
+
<radialGradient id="g2" cx="20%" cy="80%" r="60%">
|
|
12
|
+
<stop offset="0" stop-color="rgba(34,197,94,0.45)"/>
|
|
13
|
+
<stop offset="1" stop-color="rgba(34,197,94,0)"/>
|
|
14
|
+
</radialGradient>
|
|
15
|
+
</defs>
|
|
16
|
+
|
|
17
|
+
<rect width="1600" height="900" fill="url(#bg)"/>
|
|
18
|
+
<rect width="1600" height="900" fill="url(#g1)"/>
|
|
19
|
+
<rect width="1600" height="900" fill="url(#g2)"/>
|
|
20
|
+
|
|
21
|
+
<rect x="260" y="220" width="1080" height="460" rx="48" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.18)"/>
|
|
22
|
+
|
|
23
|
+
<g>
|
|
24
|
+
<rect x="320" y="280" width="180" height="30" rx="15" fill="rgba(255,255,255,0.14)"/>
|
|
25
|
+
<rect x="320" y="330" width="520" height="16" rx="8" fill="rgba(255,255,255,0.22)"/>
|
|
26
|
+
<rect x="320" y="360" width="720" height="16" rx="8" fill="rgba(255,255,255,0.18)"/>
|
|
27
|
+
<rect x="320" y="390" width="640" height="16" rx="8" fill="rgba(255,255,255,0.18)"/>
|
|
28
|
+
<rect x="320" y="450" width="900" height="14" rx="7" fill="rgba(255,255,255,0.14)"/>
|
|
29
|
+
<rect x="320" y="476" width="820" height="14" rx="7" fill="rgba(255,255,255,0.14)"/>
|
|
30
|
+
<rect x="320" y="502" width="740" height="14" rx="7" fill="rgba(255,255,255,0.14)"/>
|
|
31
|
+
</g>
|
|
32
|
+
|
|
33
|
+
<g opacity="0.9">
|
|
34
|
+
<circle cx="1200" cy="320" r="54" fill="rgba(255,255,255,0.08)"/>
|
|
35
|
+
<path d="M1186 320h28M1200 306v28" stroke="rgba(255,255,255,0.55)" stroke-width="6" stroke-linecap="round"/>
|
|
36
|
+
</g>
|
|
37
|
+
</svg>
|
|
38
|
+
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#f8fafc"/>
|
|
5
|
+
<stop offset="1" stop-color="#eef2ff"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="chip" x1="0" y1="0" x2="1" y2="1">
|
|
8
|
+
<stop offset="0" stop-color="#22c55e"/>
|
|
9
|
+
<stop offset="1" stop-color="#a78bfa"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<rect width="1600" height="900" fill="url(#bg)"/>
|
|
14
|
+
|
|
15
|
+
<g opacity="0.18">
|
|
16
|
+
<circle cx="420" cy="260" r="220" fill="#22c55e"/>
|
|
17
|
+
<circle cx="1250" cy="520" r="320" fill="#a78bfa"/>
|
|
18
|
+
</g>
|
|
19
|
+
|
|
20
|
+
<g>
|
|
21
|
+
<rect x="220" y="210" width="520" height="420" rx="36" fill="rgba(15,23,42,0.06)"/>
|
|
22
|
+
<rect x="860" y="270" width="520" height="360" rx="36" fill="rgba(15,23,42,0.06)"/>
|
|
23
|
+
</g>
|
|
24
|
+
|
|
25
|
+
<g fill="rgba(15,23,42,0.10)">
|
|
26
|
+
<rect x="270" y="260" width="220" height="44" rx="22"/>
|
|
27
|
+
<rect x="270" y="320" width="280" height="14" rx="7"/>
|
|
28
|
+
<rect x="270" y="350" width="320" height="14" rx="7"/>
|
|
29
|
+
<rect x="270" y="380" width="250" height="14" rx="7"/>
|
|
30
|
+
|
|
31
|
+
<rect x="910" y="320" width="260" height="44" rx="22" fill="url(#chip)"/>
|
|
32
|
+
<rect x="910" y="385" width="340" height="14" rx="7"/>
|
|
33
|
+
<rect x="910" y="415" width="300" height="14" rx="7"/>
|
|
34
|
+
<rect x="910" y="445" width="220" height="14" rx="7"/>
|
|
35
|
+
</g>
|
|
36
|
+
</svg>
|
|
37
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#0f172a"/>
|
|
5
|
+
<stop offset="1" stop-color="#0b1220"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="acc" x1="0" y1="0" x2="1" y2="0">
|
|
8
|
+
<stop offset="0" stop-color="#22c55e"/>
|
|
9
|
+
<stop offset="1" stop-color="#38bdf8"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<rect width="1600" height="900" fill="url(#bg)"/>
|
|
14
|
+
|
|
15
|
+
<g opacity="0.18">
|
|
16
|
+
<circle cx="420" cy="260" r="240" fill="#22c55e"/>
|
|
17
|
+
<circle cx="1220" cy="680" r="280" fill="#38bdf8"/>
|
|
18
|
+
</g>
|
|
19
|
+
|
|
20
|
+
<g fill="rgba(255,255,255,0.10)">
|
|
21
|
+
<rect x="260" y="200" width="1080" height="84" rx="42"/>
|
|
22
|
+
<rect x="260" y="320" width="1080" height="84" rx="42"/>
|
|
23
|
+
<rect x="260" y="440" width="1080" height="84" rx="42"/>
|
|
24
|
+
<rect x="260" y="560" width="1080" height="84" rx="42"/>
|
|
25
|
+
<rect x="260" y="680" width="1080" height="84" rx="42"/>
|
|
26
|
+
</g>
|
|
27
|
+
|
|
28
|
+
<g>
|
|
29
|
+
<rect x="300" y="236" width="420" height="12" rx="6" fill="rgba(255,255,255,0.22)"/>
|
|
30
|
+
<rect x="300" y="356" width="560" height="12" rx="6" fill="rgba(255,255,255,0.22)"/>
|
|
31
|
+
<rect x="300" y="476" width="520" height="12" rx="6" fill="rgba(255,255,255,0.22)"/>
|
|
32
|
+
<rect x="300" y="596" width="680" height="12" rx="6" fill="rgba(255,255,255,0.22)"/>
|
|
33
|
+
<rect x="300" y="716" width="460" height="12" rx="6" fill="rgba(255,255,255,0.22)"/>
|
|
34
|
+
</g>
|
|
35
|
+
|
|
36
|
+
<path d="M1240 240c0 0-20 110-140 120s-160 120-160 120" fill="none" stroke="url(#acc)" stroke-width="10" stroke-linecap="round" opacity="0.75"/>
|
|
37
|
+
</svg>
|
|
38
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<svg width="1200" height="630" viewBox="0 0 1200 630" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1200" y2="630" gradientUnits="userSpaceOnUse">
|
|
4
|
+
<stop offset="0" stop-color="#0B1020"/>
|
|
5
|
+
<stop offset="1" stop-color="#0F2A1B"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="card" x1="0" y1="0" x2="1" y2="1">
|
|
8
|
+
<stop offset="0" stop-color="#FFFFFF" stop-opacity="0.10"/>
|
|
9
|
+
<stop offset="1" stop-color="#FFFFFF" stop-opacity="0.04"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
<filter id="shadow" x="-30" y="-30" width="1260" height="690" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
|
12
|
+
<feDropShadow dx="0" dy="18" stdDeviation="24" flood-color="#000000" flood-opacity="0.35"/>
|
|
13
|
+
</filter>
|
|
14
|
+
</defs>
|
|
15
|
+
|
|
16
|
+
<rect width="1200" height="630" fill="url(#bg)"/>
|
|
17
|
+
|
|
18
|
+
<g filter="url(#shadow)">
|
|
19
|
+
<rect x="120" y="126" width="960" height="378" rx="36" fill="url(#card)" stroke="#FFFFFF" stroke-opacity="0.12"/>
|
|
20
|
+
</g>
|
|
21
|
+
|
|
22
|
+
<circle cx="240" cy="252" r="48" fill="#34D399" fill-opacity="0.22"/>
|
|
23
|
+
<circle cx="316" cy="280" r="14" fill="#34D399" fill-opacity="0.55"/>
|
|
24
|
+
|
|
25
|
+
<path d="M240 360H960" stroke="#FFFFFF" stroke-opacity="0.10" stroke-width="2"/>
|
|
26
|
+
<path d="M240 400H840" stroke="#FFFFFF" stroke-opacity="0.08" stroke-width="2"/>
|
|
27
|
+
<path d="M240 440H900" stroke="#FFFFFF" stroke-opacity="0.06" stroke-width="2"/>
|
|
28
|
+
|
|
29
|
+
<text x="240" y="332" fill="#FFFFFF" fill-opacity="0.92" font-family="ui-sans-serif, system-ui" font-size="54" font-weight="700" letter-spacing="-0.8">
|
|
30
|
+
Markdown Kitchen Sink
|
|
31
|
+
</text>
|
|
32
|
+
<text x="240" y="520" fill="#FFFFFF" fill-opacity="0.70" font-family="ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, Liberation Mono, Courier New, monospace" font-size="18" letter-spacing="0.6">
|
|
33
|
+
tables • lists • code • quotes • images
|
|
34
|
+
</text>
|
|
35
|
+
</svg>
|
|
36
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#0b1220"/>
|
|
5
|
+
<stop offset="1" stop-color="#0f172a"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="acc" x1="0" y1="0" x2="1" y2="0">
|
|
8
|
+
<stop offset="0" stop-color="#38bdf8"/>
|
|
9
|
+
<stop offset="1" stop-color="#22c55e"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<rect width="1600" height="900" fill="url(#bg)"/>
|
|
14
|
+
<g opacity="0.18">
|
|
15
|
+
<circle cx="460" cy="520" r="320" fill="#38bdf8"/>
|
|
16
|
+
<circle cx="1180" cy="300" r="260" fill="#22c55e"/>
|
|
17
|
+
</g>
|
|
18
|
+
|
|
19
|
+
<g>
|
|
20
|
+
<rect x="260" y="250" width="520" height="400" rx="40" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.16)"/>
|
|
21
|
+
<rect x="820" y="250" width="520" height="400" rx="40" fill="rgba(255,255,255,0.08)" stroke="rgba(255,255,255,0.16)"/>
|
|
22
|
+
<path d="M820 450h-40c-40 0-60-20-60-60v-20c0-40-20-60-60-60h-60" fill="none" stroke="url(#acc)" stroke-width="10" stroke-linecap="round" opacity="0.85"/>
|
|
23
|
+
</g>
|
|
24
|
+
|
|
25
|
+
<g fill="rgba(255,255,255,0.20)">
|
|
26
|
+
<rect x="320" y="320" width="240" height="16" rx="8"/>
|
|
27
|
+
<rect x="320" y="352" width="360" height="16" rx="8"/>
|
|
28
|
+
<rect x="320" y="384" width="320" height="16" rx="8"/>
|
|
29
|
+
<rect x="320" y="450" width="420" height="12" rx="6" opacity="0.8"/>
|
|
30
|
+
<rect x="320" y="474" width="380" height="12" rx="6" opacity="0.8"/>
|
|
31
|
+
</g>
|
|
32
|
+
|
|
33
|
+
<g fill="rgba(255,255,255,0.20)">
|
|
34
|
+
<rect x="880" y="320" width="260" height="16" rx="8"/>
|
|
35
|
+
<rect x="880" y="352" width="360" height="16" rx="8"/>
|
|
36
|
+
<rect x="880" y="384" width="280" height="16" rx="8"/>
|
|
37
|
+
<rect x="880" y="450" width="420" height="12" rx="6" opacity="0.8"/>
|
|
38
|
+
<rect x="880" y="474" width="340" height="12" rx="6" opacity="0.8"/>
|
|
39
|
+
</g>
|
|
40
|
+
</svg>
|
|
41
|
+
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#0b1220"/>
|
|
5
|
+
<stop offset="0.55" stop-color="#0f172a"/>
|
|
6
|
+
<stop offset="1" stop-color="#052e1b"/>
|
|
7
|
+
</linearGradient>
|
|
8
|
+
<radialGradient id="glow" cx="30%" cy="20%" r="60%">
|
|
9
|
+
<stop offset="0" stop-color="rgba(52,211,153,0.55)"/>
|
|
10
|
+
<stop offset="1" stop-color="rgba(52,211,153,0)"/>
|
|
11
|
+
</radialGradient>
|
|
12
|
+
<radialGradient id="glow2" cx="80%" cy="70%" r="60%">
|
|
13
|
+
<stop offset="0" stop-color="rgba(56,189,248,0.45)"/>
|
|
14
|
+
<stop offset="1" stop-color="rgba(56,189,248,0)"/>
|
|
15
|
+
</radialGradient>
|
|
16
|
+
</defs>
|
|
17
|
+
|
|
18
|
+
<rect width="1600" height="900" fill="url(#bg)"/>
|
|
19
|
+
<rect width="1600" height="900" fill="url(#glow)"/>
|
|
20
|
+
<rect width="1600" height="900" fill="url(#glow2)"/>
|
|
21
|
+
|
|
22
|
+
<g opacity="0.35" stroke="rgba(255,255,255,0.35)">
|
|
23
|
+
<path d="M120 220c220-110 420-110 640 0s420 110 640 0" fill="none" stroke-width="2"/>
|
|
24
|
+
<path d="M120 280c220-110 420-110 640 0s420 110 640 0" fill="none" stroke-width="2" opacity="0.7"/>
|
|
25
|
+
<path d="M120 340c220-110 420-110 640 0s420 110 640 0" fill="none" stroke-width="2" opacity="0.5"/>
|
|
26
|
+
</g>
|
|
27
|
+
|
|
28
|
+
<g opacity="0.22">
|
|
29
|
+
<rect x="240" y="520" width="1120" height="180" rx="36" fill="rgba(255,255,255,0.08)"/>
|
|
30
|
+
<rect x="300" y="570" width="420" height="18" rx="9" fill="rgba(255,255,255,0.20)"/>
|
|
31
|
+
<rect x="300" y="610" width="680" height="12" rx="6" fill="rgba(255,255,255,0.14)"/>
|
|
32
|
+
<rect x="300" y="636" width="520" height="12" rx="6" fill="rgba(255,255,255,0.14)"/>
|
|
33
|
+
</g>
|
|
34
|
+
</svg>
|
|
35
|
+
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="1600" height="900" viewBox="0 0 1600 900">
|
|
2
|
+
<defs>
|
|
3
|
+
<linearGradient id="bg" x1="0" y1="0" x2="1" y2="1">
|
|
4
|
+
<stop offset="0" stop-color="#fff7ed"/>
|
|
5
|
+
<stop offset="1" stop-color="#f0fdf4"/>
|
|
6
|
+
</linearGradient>
|
|
7
|
+
<linearGradient id="acc" x1="0" y1="0" x2="1" y2="1">
|
|
8
|
+
<stop offset="0" stop-color="#f97316"/>
|
|
9
|
+
<stop offset="1" stop-color="#22c55e"/>
|
|
10
|
+
</linearGradient>
|
|
11
|
+
</defs>
|
|
12
|
+
|
|
13
|
+
<rect width="1600" height="900" fill="url(#bg)"/>
|
|
14
|
+
<g opacity="0.12">
|
|
15
|
+
<circle cx="400" cy="220" r="260" fill="#f97316"/>
|
|
16
|
+
<circle cx="1220" cy="620" r="320" fill="#22c55e"/>
|
|
17
|
+
</g>
|
|
18
|
+
|
|
19
|
+
<rect x="300" y="220" width="1000" height="460" rx="48" fill="rgba(15,23,42,0.06)"/>
|
|
20
|
+
<g transform="translate(420 340)">
|
|
21
|
+
<circle cx="60" cy="300" r="36" fill="url(#acc)"/>
|
|
22
|
+
<path d="M60 210c84 0 150 66 150 150" fill="none" stroke="url(#acc)" stroke-width="24" stroke-linecap="round"/>
|
|
23
|
+
<path d="M60 120c134 0 240 106 240 240" fill="none" stroke="url(#acc)" stroke-width="24" stroke-linecap="round" opacity="0.8"/>
|
|
24
|
+
</g>
|
|
25
|
+
|
|
26
|
+
<g fill="rgba(15,23,42,0.12)">
|
|
27
|
+
<rect x="780" y="330" width="420" height="16" rx="8"/>
|
|
28
|
+
<rect x="780" y="362" width="340" height="16" rx="8"/>
|
|
29
|
+
<rect x="780" y="420" width="460" height="14" rx="7"/>
|
|
30
|
+
<rect x="780" y="446" width="520" height="14" rx="7"/>
|
|
31
|
+
<rect x="780" y="472" width="480" height="14" rx="7"/>
|
|
32
|
+
</g>
|
|
33
|
+
</svg>
|
|
34
|
+
|
package/svelte.config.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import adapter from '@sveltejs/adapter-auto';
|
|
2
|
+
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
|
|
3
|
+
import { mdsvex } from 'mdsvex';
|
|
4
|
+
import remarkGfm from 'remark-gfm';
|
|
5
|
+
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
|
|
6
|
+
import rehypeSlug from 'rehype-slug';
|
|
7
|
+
import rehypeShiki from '@shikijs/rehype';
|
|
8
|
+
|
|
9
|
+
/** @type {import('unified').Plugin} */
|
|
10
|
+
function rehypeStripPreTabindex() {
|
|
11
|
+
/** @param {any} node */
|
|
12
|
+
function walk(node) {
|
|
13
|
+
if (!node || typeof node !== 'object') return;
|
|
14
|
+
if (node.type === 'element' && node.tagName === 'pre' && node.properties) {
|
|
15
|
+
delete node.properties.tabindex;
|
|
16
|
+
delete node.properties.tabIndex;
|
|
17
|
+
}
|
|
18
|
+
if (Array.isArray(node.children)) node.children.forEach(walk);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return (tree) => walk(tree);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** @type {import('mdsvex').MdsvexOptions} */
|
|
25
|
+
const mdsvexConfig = {
|
|
26
|
+
extensions: ['.md'],
|
|
27
|
+
frontmatter: {
|
|
28
|
+
marker: '-',
|
|
29
|
+
type: 'yaml',
|
|
30
|
+
parse: () => undefined
|
|
31
|
+
},
|
|
32
|
+
highlight: false,
|
|
33
|
+
remarkPlugins: [remarkGfm],
|
|
34
|
+
rehypePlugins: [
|
|
35
|
+
rehypeSlug,
|
|
36
|
+
[
|
|
37
|
+
rehypeAutolinkHeadings,
|
|
38
|
+
{
|
|
39
|
+
behavior: 'wrap',
|
|
40
|
+
properties: {
|
|
41
|
+
className: ['heading-anchor']
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
],
|
|
45
|
+
[
|
|
46
|
+
rehypeShiki,
|
|
47
|
+
{
|
|
48
|
+
themes: {
|
|
49
|
+
light: 'one-light',
|
|
50
|
+
dark: 'github-dark-default'
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
],
|
|
54
|
+
rehypeStripPreTabindex
|
|
55
|
+
]
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
/** @type {import('@sveltejs/kit').Config} */
|
|
59
|
+
const config = {
|
|
60
|
+
extensions: ['.svelte', '.md'],
|
|
61
|
+
preprocess: [mdsvex(mdsvexConfig), vitePreprocess()],
|
|
62
|
+
kit: {
|
|
63
|
+
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
|
|
64
|
+
// If your environment is not supported, or you settled on a specific environment, switch out the adapter.
|
|
65
|
+
// See https://svelte.dev/docs/kit/adapters for more information about adapters.
|
|
66
|
+
adapter: adapter()
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
export default config;
|