diff --git a/frontend/src/pages/index.astro b/frontend/src/pages/index.astro
index 2f0957e..ec93663 100644
--- a/frontend/src/pages/index.astro
+++ b/frontend/src/pages/index.astro
@@ -10,14 +10,26 @@ interface Post {
let posts: Post[] = [];
let error = '';
+let siteConfig = {
+ welcome_title: "Welcome to my blog",
+ welcome_subtitle: "Thoughts on software, design, and building things with Rust and Astro."
+};
try {
- const response = await fetch(`${API_URL}/api/posts`);
- if (response.ok) {
- posts = await response.json();
+ const [postsRes, configRes] = await Promise.all([
+ fetch(`${API_URL}/api/posts`),
+ fetch(`${API_URL}/api/config`)
+ ]);
+
+ if (postsRes.ok) {
+ posts = await postsRes.json();
} else {
error = 'Failed to fetch posts';
}
+
+ if (configRes.ok) {
+ siteConfig = await configRes.json();
+ }
} catch (e) {
const cause = (e as any)?.cause;
error = `Could not connect to backend at ${API_URL}: ${e instanceof Error ? e.message : String(e)}${cause ? ' (Cause: ' + (cause.message || cause.code || JSON.stringify(cause)) + ')' : ''}`;
@@ -25,6 +37,7 @@ try {
}
function formatSlug(slug: string) {
+ if (!slug) return '';
return slug
.split('-')
.map(word => word.charAt(0).toUpperCase() + word.slice(1))
@@ -36,10 +49,10 @@ function formatSlug(slug: string) {
- Thoughts on software, design, and building things with Rust and Astro.
+ {siteConfig.welcome_subtitle}
@@ -49,9 +62,9 @@ function formatSlug(slug: string) {
{error}
)}
-
+
{posts.length === 0 && !error && (
-
+
No posts found yet. Add some .md files to the data/posts directory!
)}
@@ -63,7 +76,7 @@ function formatSlug(slug: string) {
{formatSlug(post.slug)}
-
+
{post.excerpt || `Read more about ${formatSlug(post.slug)}...`}
diff --git a/frontend/src/styles/global.css b/frontend/src/styles/global.css
index 066658f..b6f063c 100644
--- a/frontend/src/styles/global.css
+++ b/frontend/src/styles/global.css
@@ -66,10 +66,10 @@
}
.latte {
- --crust: #dce0e8; --mantle: #e6e9ef; --base: #eff1f5;
- --surface0: #ccd0da; --surface1: #bcc0cc; --surface2: #acb0be;
+ --crust: #e6e9ef; --mantle: #dce0e8; --base: #eff1f5;
+ --surface0: #e6e9ef; --surface1: #bcc0cc; --surface2: #acb0be;
--overlay0: #9ca0b0; --overlay1: #8c8fa1; --overlay2: #7c7f93;
- --text: #4c4f69; --subtext0: #5c5f77; --subtext1: #6c6f85;
+ --text: #1e1e2e; --subtext0: #4c4f69; --subtext1: #5c5f77;
--blue: #1e66f5; --lavender: #7287fd; --sapphire: #209fb5;
--sky: #04a5e5; --teal: #179299; --green: #40a02b;
--yellow: #df8e1d; --peach: #fe640b; --maroon: #e64553;
@@ -84,6 +84,24 @@ body {
transition: background-color 0.3s ease, color 0.3s ease;
}
+/* Dynamic CodeMirror Theme */
+.cm-s-narlblog.CodeMirror {
+ background: var(--crust);
+ color: var(--text);
+ border: 1px solid var(--surface1);
+}
+.cm-s-narlblog .cm-header { color: var(--mauve); font-weight: bold; }
+.cm-s-narlblog .cm-string { color: var(--green); }
+.cm-s-narlblog .cm-link { color: var(--blue); text-decoration: underline; }
+.cm-s-narlblog .cm-url { color: var(--sky); }
+.cm-s-narlblog .cm-comment { color: var(--subtext0); font-style: italic; }
+.cm-s-narlblog .cm-quote { color: var(--peach); }
+.cm-s-narlblog .CodeMirror-cursor { border-left-color: var(--text); }
+.cm-s-narlblog.cm-fat-cursor .CodeMirror-cursor { background: var(--text); }
+.cm-s-narlblog .CodeMirror-selected { background: var(--surface2); }
+.cm-s-narlblog .CodeMirror-line::selection, .cm-s-narlblog .CodeMirror-line > span::selection, .cm-s-narlblog .CodeMirror-line > span > span::selection { background: var(--surface2); }
+.cm-s-narlblog .CodeMirror-line::-moz-selection, .cm-s-narlblog .CodeMirror-line > span::-moz-selection, .cm-s-narlblog .CodeMirror-line > span > span::-moz-selection { background: var(--surface2); }
+
/* Typography styles for Markdown */
.prose h1 { @apply text-3xl md:text-4xl font-bold mb-4 md:mb-6 text-mauve; }
.prose h2 { @apply text-2xl md:text-3xl font-semibold mb-3 md:mb-4 mt-6 md:mt-8 text-lavender; }