fixed theming issues

This commit is contained in:
2026-03-26 00:26:07 +01:00
parent 6ba897d27f
commit 798552d16f
5 changed files with 84 additions and 42 deletions

View File

@@ -23,6 +23,8 @@ struct AppState {
struct SiteConfig {
title: String,
subtitle: String,
welcome_title: String,
welcome_subtitle: String,
footer: String,
favicon: String,
theme: String,
@@ -34,6 +36,8 @@ impl Default for SiteConfig {
Self {
title: "Narlblog".to_string(),
subtitle: "A clean, modern blog".to_string(),
welcome_title: "Welcome to my blog".to_string(),
welcome_subtitle: "Thoughts on software, design, and building things with Rust and Astro.".to_string(),
footer: "Built with Rust & Astro".to_string(),
favicon: "/favicon.svg".to_string(),
theme: "mocha".to_string(),

View File

@@ -9,33 +9,6 @@ import Layout from '../../layouts/Layout.astro';
<script is:inline src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/codemirror.min.js"></script>
<script is:inline src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/mode/markdown/markdown.min.js"></script>
<script is:inline src="https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.65.16/keymap/vim.min.js"></script>
<style is:global>
.CodeMirror {
height: auto;
min-height: 400px;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
border-radius: 0.5rem;
background: var(--crust);
color: var(--text);
border: 1px solid var(--surface1);
padding: 1rem;
}
.CodeMirror-focused {
border-color: var(--mauve);
}
.CodeMirror-scroll {
min-height: 400px;
}
.cm-s-default .cm-header { color: var(--mauve); font-weight: bold; }
.cm-s-default .cm-string { color: var(--green); }
.cm-s-default .cm-link { color: var(--blue); text-decoration: underline; }
.cm-s-default .cm-url { color: var(--sky); }
.cm-s-default .cm-comment { color: var(--subtext0); font-style: italic; }
.cm-s-default .cm-quote { color: var(--peach); }
.cm-fat-cursor .CodeMirror-cursor { background: var(--text); }
.cm-animate-fat-cursor { background-color: var(--text); }
</style>
<div class="glass p-12 mb-12" id="editor-content" style="display: none;">
<header class="mb-12 border-b border-white/5 pb-12 flex justify-between items-center">
@@ -406,3 +379,31 @@ import Layout from '../../layouts/Layout.astro';
}
</script>
</Layout>
ect slug on edit
delBtn?.classList.remove('hidden');
fetch(`/api/posts/${encodeURIComponent(editSlug)}`)
.then(res => res.json())
.then(data => {
if (data.content) {
editor.setValue(data.content);
}
})
.catch(() => showAlert('Failed to load post.', 'error'));
}
function showAlert(msg: string, type: 'success' | 'error') {
const alertEl = document.getElementById('alert');
if (alertEl) {
alertEl.textContent = msg;
alertEl.className = `p-4 rounded-lg mb-6 ${type === 'success' ? 'bg-green/20 text-green border border-green/30' : 'bg-red/20 text-red border border-red/30'}`;
alertEl.classList.remove('hidden');
setTimeout(() => { alertEl.classList.add('hidden'); }, 4000);
}
}
</script>
</Layout>
setTimeout(() => { alertEl.classList.add('hidden'); }, 4000);
}
}
</script>
</Layout>

View File

@@ -22,14 +22,20 @@ import Layout from '../../layouts/Layout.astro';
<h2 class="text-xl font-bold text-lavender border-l-4 border-lavender pl-4">General Identity</h2>
<div class="grid md:grid-cols-2 gap-6">
<div>
<label for="title" class="block text-sm font-medium text-subtext1 mb-2">Blog Title</label>
<label for="title" class="block text-sm font-medium text-subtext1 mb-2">Blog Title (Nav)</label>
<input type="text" id="title" required class="w-full bg-crust border border-surface1 rounded-lg px-4 py-3 text-text focus:outline-none focus:border-mauve transition-colors" />
<p class="text-[10px] text-subtext0 mt-1">Main name of your blog.</p>
</div>
<div>
<label for="subtitle" class="block text-sm font-medium text-subtext1 mb-2">Subtitle</label>
<label for="subtitle" class="block text-sm font-medium text-subtext1 mb-2">Nav Subtitle</label>
<input type="text" id="subtitle" required class="w-full bg-crust border border-surface1 rounded-lg px-4 py-3 text-text focus:outline-none focus:border-mauve transition-colors" />
<p class="text-[10px] text-subtext0 mt-1">Short description shown under the title.</p>
</div>
<div>
<label for="welcome_title" class="block text-sm font-medium text-subtext1 mb-2">Welcome Title (Frontpage)</label>
<input type="text" id="welcome_title" required class="w-full bg-crust border border-surface1 rounded-lg px-4 py-3 text-text focus:outline-none focus:border-mauve transition-colors" />
</div>
<div>
<label for="welcome_subtitle" class="block text-sm font-medium text-subtext1 mb-2">Welcome Subtitle</label>
<input type="text" id="welcome_subtitle" required class="w-full bg-crust border border-surface1 rounded-lg px-4 py-3 text-text focus:outline-none focus:border-mauve transition-colors" />
</div>
</div>
<div>

View File

@@ -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) {
<div class="space-y-6 md:space-y-8">
<section class="text-center py-6 md:py-12">
<h1 class="text-3xl md:text-5xl font-extrabold mb-3 md:mb-4 pb-2 md:pb-4 leading-tight bg-clip-text text-transparent bg-gradient-to-r from-mauve via-blue to-teal">
Welcome to my blog
{siteConfig.welcome_title}
</h1>
<p class="text-subtext1 text-base md:text-lg max-w-2xl mx-auto px-4 md:px-0">
Thoughts on software, design, and building things with Rust and Astro.
{siteConfig.welcome_subtitle}
</p>
</section>
@@ -49,9 +62,9 @@ function formatSlug(slug: string) {
{error}
</div>
)}
{posts.length === 0 && !error && (
<div class="glass p-8 md:p-12 text-center text-subtext0 text-sm md:text-base">
<div class="glass p-8 md:p-12 text-center text-subtext1 text-sm md:text-base">
<p>No posts found yet. Add some .md files to the data/posts directory!</p>
</div>
)}
@@ -63,7 +76,7 @@ function formatSlug(slug: string) {
<h2 class="text-xl md:text-3xl font-bold text-lavender group-hover:text-mauve transition-colors mb-2 md:mb-3">
{formatSlug(post.slug)}
</h2>
<p class="text-subtext1 text-sm md:text-base leading-relaxed line-clamp-3">
<p class="text-text text-sm md:text-base leading-relaxed line-clamp-3">
{post.excerpt || `Read more about ${formatSlug(post.slug)}...`}
</p>
</div>

View File

@@ -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; }