on master help sign in
24 files changed+747
since splitsnapshots
unifiedsplit
.gitignore+1 dhall/layouts/index.dhall+26 dhall/layouts/package.dhall+5 dhall/layouts/page.dhall+22 dhall/layouts/post.dhall+26 dhall/layouts/rss.dhall+13 dhall/package.dhall+10 dhall/types/Content.dhall+1 dhall/types/Date.dhall+1 dhall/types/NavItem.dhall+1 dhall/types/Page.dhall+5 dhall/types/Post.dhall+14 dhall/types/Site.dhall+22 dhall/types/package.dhall+16 flake.lock+27 flake.nix+34 nix/buildSite.nix+36 nix/builder.sh+227 result+1 templates/default/content/about.md+5 templates/default/content/posts/hello-world.md+21 templates/default/flake.nix+17 templates/default/site.dhall+28 theme/style.css+188
.gitignorenew file+1
@@ -0,0 +1 @@
1+result
dhall/layouts/index.dhallnew file+26
@@ -0,0 +1,26 @@
1+\(args : { siteTitle : Text, description : Text, navHtml : Text, postsHtml : Text }) ->
2+''
3+<!DOCTYPE html>
4+<html lang="en">
5+<head>
6+ <meta charset="utf-8">
7+ <meta name="viewport" content="width=device-width, initial-scale=1">
8+ <title>${args.siteTitle}</title>
9+ <link rel="stylesheet" href="/style.css">
10+ <link rel="alternate" type="application/rss+xml" title="${args.siteTitle}" href="/rss.xml">
11+</head>
12+<body>
13+ <nav>${args.navHtml}</nav>
14+ <main>
15+ <header class="site-header">
16+ <h1>${args.siteTitle}</h1>
17+ <p>${args.description}</p>
18+ </header>
19+ <section class="post-list">
20+ ${args.postsHtml}
21+ </section>
22+ </main>
23+ <footer><p>&copy; ${args.siteTitle}</p></footer>
24+</body>
25+</html>
26+''
dhall/layouts/package.dhallnew file+5
@@ -0,0 +1,5 @@
1+{ page = ./page.dhall
2+, post = ./post.dhall
3+, index = ./index.dhall
4+, rss = ./rss.dhall
5+}
dhall/layouts/page.dhallnew file+22
@@ -0,0 +1,22 @@
1+\(args : { siteTitle : Text, pageTitle : Text, navHtml : Text, contentHtml : Text }) ->
2+''
3+<!DOCTYPE html>
4+<html lang="en">
5+<head>
6+ <meta charset="utf-8">
7+ <meta name="viewport" content="width=device-width, initial-scale=1">
8+ <title>${args.pageTitle} - ${args.siteTitle}</title>
9+ <link rel="stylesheet" href="/style.css">
10+</head>
11+<body>
12+ <nav>${args.navHtml}</nav>
13+ <main>
14+ <article>
15+ <h1>${args.pageTitle}</h1>
16+ ${args.contentHtml}
17+ </article>
18+ </main>
19+ <footer><p>&copy; ${args.siteTitle}</p></footer>
20+</body>
21+</html>
22+''
dhall/layouts/post.dhallnew file+26
@@ -0,0 +1,26 @@
1+\(args : { siteTitle : Text, postTitle : Text, dateStr : Text, tagsHtml : Text, navHtml : Text, contentHtml : Text }) ->
2+''
3+<!DOCTYPE html>
4+<html lang="en">
5+<head>
6+ <meta charset="utf-8">
7+ <meta name="viewport" content="width=device-width, initial-scale=1">
8+ <title>${args.postTitle} - ${args.siteTitle}</title>
9+ <link rel="stylesheet" href="/style.css">
10+</head>
11+<body>
12+ <nav>${args.navHtml}</nav>
13+ <main>
14+ <article>
15+ <header>
16+ <h1>${args.postTitle}</h1>
17+ <time>${args.dateStr}</time>
18+ ${args.tagsHtml}
19+ </header>
20+ ${args.contentHtml}
21+ </article>
22+ </main>
23+ <footer><p>&copy; ${args.siteTitle}</p></footer>
24+</body>
25+</html>
26+''
dhall/layouts/rss.dhallnew file+13
@@ -0,0 +1,13 @@
1+\(args : { siteTitle : Text, baseUrl : Text, description : Text, itemsXml : Text }) ->
2+''
3+<?xml version="1.0" encoding="UTF-8"?>
4+<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
5+<channel>
6+ <title>${args.siteTitle}</title>
7+ <link>${args.baseUrl}</link>
8+ <description>${args.description}</description>
9+ <atom:link href="${args.baseUrl}/rss.xml" rel="self" type="application/rss+xml"/>
10+ ${args.itemsXml}
11+</channel>
12+</rss>
13+''
dhall/package.dhallnew file+10
@@ -0,0 +1,10 @@
1+let types = ./types/package.dhall
2+
3+in { Site = types.Site
4+ , Page = types.Page
5+ , Post = types.Post
6+ , Content = types.content
7+ , Date = types.Date
8+ , NavItem = types.NavItem
9+ , layouts = ./layouts/package.dhall
10+ }
dhall/types/Content.dhallnew file+1
@@ -0,0 +1 @@
1+{ tag : Text, value : Text }
dhall/types/Date.dhallnew file+1
@@ -0,0 +1 @@
1+{ year : Natural, month : Natural, day : Natural }
dhall/types/NavItem.dhallnew file+1
@@ -0,0 +1 @@
1+{ label : Text, url : Text }
dhall/types/Page.dhallnew file+5
@@ -0,0 +1,5 @@
1+let Content = ./Content.dhall
2+
3+in { Type = { title : Text, slug : Text, content : Content }
4+ , default = {=}
5+ }
dhall/types/Post.dhallnew file+14
@@ -0,0 +1,14 @@
1+let Content = ./Content.dhall
2+
3+let DateType = ./Date.dhall
4+
5+in { Type =
6+ { title : Text
7+ , slug : Text
8+ , content : Content
9+ , date : DateType
10+ , tags : List Text
11+ , draft : Bool
12+ }
13+ , default = { tags = [] : List Text, draft = False }
14+ }
dhall/types/Site.dhallnew file+22
@@ -0,0 +1,22 @@
1+let Page = ./Page.dhall
2+
3+let Post = ./Post.dhall
4+
5+let NavItem = ./NavItem.dhall
6+
7+in { Type =
8+ { title : Text
9+ , baseUrl : Text
10+ , author : Text
11+ , description : Text
12+ , nav : List NavItem
13+ , pages : List Page.Type
14+ , posts : List Post.Type
15+ }
16+ , default =
17+ { description = ""
18+ , nav = [] : List NavItem
19+ , pages = [] : List Page.Type
20+ , posts = [] : List Post.Type
21+ }
22+ }
dhall/types/package.dhallnew file+16
@@ -0,0 +1,16 @@
1+let Content = ./Content.dhall
2+
3+in { Date = ./Date.dhall
4+ , Content = Content
5+ , NavItem = ./NavItem.dhall
6+ , Page = ./Page.dhall
7+ , Post = ./Post.dhall
8+ , Site = ./Site.dhall
9+ , content =
10+ { File = \(path : Text) -> { tag = "File", value = path } : Content
11+ , Inline =
12+ \(markdown : Text) -> { tag = "Inline", value = markdown } : Content
13+ , DhallHtml =
14+ \(path : Text) -> { tag = "DhallHtml", value = path } : Content
15+ }
16+ }
flake.locknew file+27
@@ -0,0 +1,27 @@
1+{
2+ "nodes": {
3+ "nixpkgs": {
4+ "locked": {
5+ "lastModified": 1771369470,
6+ "narHash": "sha256-0NBlEBKkN3lufyvFegY4TYv5mCNHbi5OmBDrzihbBMQ=",
7+ "owner": "NixOS",
8+ "repo": "nixpkgs",
9+ "rev": "0182a361324364ae3f436a63005877674cf45efb",
10+ "type": "github"
11+ },
12+ "original": {
13+ "owner": "NixOS",
14+ "ref": "nixos-unstable",
15+ "repo": "nixpkgs",
16+ "type": "github"
17+ }
18+ },
19+ "root": {
20+ "inputs": {
21+ "nixpkgs": "nixpkgs"
22+ }
23+ }
24+ },
25+ "root": "root",
26+ "version": 7
27+}
flake.nixnew file+34
@@ -0,0 +1,34 @@
1+{
2+ description = "static-dhall: an opinionated static site generator using Dhall and Nix";
3+
4+ inputs = {
5+ nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
6+ };
7+
8+ outputs = { self, nixpkgs }:
9+ let
10+ supportedSystems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ];
11+ forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems (system:
12+ f {
13+ pkgs = nixpkgs.legacyPackages.${system};
14+ inherit system;
15+ }
16+ );
17+ in
18+ {
19+ lib = forAllSystems ({ pkgs, ... }: {
20+ buildSite = import ./nix/buildSite.nix { inherit pkgs; };
21+ });
22+
23+ packages = forAllSystems ({ pkgs, ... }: {
24+ example = import ./nix/buildSite.nix { inherit pkgs; } {
25+ src = ./templates/default;
26+ };
27+ });
28+
29+ templates.default = {
30+ path = ./templates/default;
31+ description = "A basic static-dhall site";
32+ };
33+ };
34+}
nix/buildSite.nixnew file+36
@@ -0,0 +1,36 @@
1+{ pkgs }:
2+
3+{ src
4+, layoutsDir ? ../dhall/layouts
5+, themeDir ? ../theme
6+, dhallPackage ? ../dhall/package.dhall
7+}:
8+
9+pkgs.stdenv.mkDerivation {
10+ name = "static-dhall-site";
11+
12+ inherit src;
13+
14+ nativeBuildInputs = with pkgs; [
15+ dhall
16+ dhall-json
17+ pandoc
18+ jq
19+ ];
20+
21+ buildPhase = ''
22+ export HOME=$(mktemp -d)
23+
24+ # Copy source to a writable directory and add .static-dhall symlink
25+ workdir=$(mktemp -d)
26+ cp -r $src/* "$workdir/"
27+ ln -s ${../dhall} "$workdir/.static-dhall"
28+
29+ export layoutsDir=${layoutsDir}
30+ export themeDir=${themeDir}
31+ export src="$workdir"
32+ bash ${../nix/builder.sh}
33+ '';
34+
35+ dontInstall = true;
36+}
nix/builder.shnew file+227
@@ -0,0 +1,227 @@
1+#!/usr/bin/env bash
2+set -euo pipefail
3+
4+# Inputs (set by Nix derivation):
5+# $src - user's site source directory
6+# $out - Nix output path
7+# $layoutsDir - path to our default layouts
8+# $themeDir - path to our theme directory
9+
10+tmpdir=$(mktemp -d)
11+trap 'rm -rf "$tmpdir"' EXIT
12+
13+mkdir -p "$out"
14+
15+# --- Step 1: Generate manifest from site.dhall ---
16+echo "Generating site manifest..."
17+manifest="$tmpdir/manifest.json"
18+dhall-to-json --file "$src/site.dhall" > "$manifest"
19+
20+# --- Step 2: Extract site metadata ---
21+siteTitle=$(jq -r '.title' "$manifest")
22+baseUrl=$(jq -r '.baseUrl' "$manifest")
23+description=$(jq -r '.description' "$manifest")
24+
25+# --- Step 3: Render nav HTML ---
26+navHtmlFile="$tmpdir/nav.txt"
27+jq -r '.nav[] | "<a href=\"\(.url)\">\(.label)</a>"' "$manifest" \
28+ | tr '\n' ' ' > "$navHtmlFile"
29+
30+# --- Helper: render content ---
31+render_content() {
32+ local content_json="$1"
33+ local content_type content_value
34+ content_type=$(echo "$content_json" | jq -r '.tag')
35+ content_value=$(echo "$content_json" | jq -r '.value')
36+
37+ case "$content_type" in
38+ File)
39+ pandoc "$src/$content_value" -f markdown -t html --no-highlight
40+ ;;
41+ Inline)
42+ echo "$content_value" | pandoc -f markdown -t html --no-highlight
43+ ;;
44+ DhallHtml)
45+ dhall text --file "$src/$content_value"
46+ ;;
47+ *)
48+ echo "Unknown content type: $content_type" >&2
49+ exit 1
50+ ;;
51+ esac
52+}
53+
54+# --- Helper: format date ---
55+format_date() {
56+ local date_json="$1"
57+ local year month day
58+ year=$(echo "$date_json" | jq -r '.year')
59+ month=$(echo "$date_json" | jq -r '.month')
60+ day=$(echo "$date_json" | jq -r '.day')
61+ printf "%04d-%02d-%02d" "$year" "$month" "$day"
62+}
63+
64+# --- Helper: render tags HTML ---
65+render_tags() {
66+ local tags_json="$1"
67+ local count
68+ count=$(echo "$tags_json" | jq -r 'length')
69+ if [ "$count" -eq 0 ]; then
70+ echo ""
71+ return
72+ fi
73+ local result='<ul class="tags">'
74+ while IFS= read -r tag; do
75+ result+="<li>$tag</li>"
76+ done < <(echo "$tags_json" | jq -r '.[]')
77+ result+='</ul>'
78+ echo "$result"
79+}
80+
81+# --- Helper: apply a Dhall layout ---
82+apply_layout() {
83+ local layout_file="$1"
84+ local args_file="$2"
85+ dhall text <<DHALL
86+let layout = $layout_file
87+let args = $args_file
88+in layout args
89+DHALL
90+}
91+
92+# --- Step 4: Build pages ---
93+echo "Building pages..."
94+page_count=$(jq -r '.pages | length' "$manifest")
95+for ((i = 0; i < page_count; i++)); do
96+ page_json=$(jq -r ".pages[$i]" "$manifest")
97+ pageTitle=$(echo "$page_json" | jq -r '.title')
98+ pageSlug=$(echo "$page_json" | jq -r '.slug')
99+ content_json=$(echo "$page_json" | jq -r '.content')
100+
101+ echo " Page: $pageTitle ($pageSlug)"
102+
103+ contentFile="$tmpdir/content.txt"
104+ render_content "$content_json" > "$contentFile"
105+
106+ echo -n "$siteTitle" > "$tmpdir/siteTitle.txt"
107+ echo -n "$pageTitle" > "$tmpdir/pageTitle.txt"
108+
109+ argsFile="$tmpdir/args.dhall"
110+ cat > "$argsFile" <<DHALL
111+{ siteTitle = $tmpdir/siteTitle.txt as Text
112+, pageTitle = $tmpdir/pageTitle.txt as Text
113+, navHtml = $navHtmlFile as Text
114+, contentHtml = $contentFile as Text
115+}
116+DHALL
117+
118+ outDir="$out/$pageSlug"
119+ mkdir -p "$outDir"
120+ apply_layout "$layoutsDir/page.dhall" "$argsFile" > "$outDir/index.html"
121+done
122+
123+# --- Step 5: Build posts ---
124+echo "Building posts..."
125+post_count=$(jq -r '.posts | length' "$manifest")
126+postsHtmlFile="$tmpdir/posts_list.txt"
127+rssItemsFile="$tmpdir/rss_items.txt"
128+> "$postsHtmlFile"
129+> "$rssItemsFile"
130+
131+for ((i = 0; i < post_count; i++)); do
132+ post_json=$(jq -r ".posts[$i]" "$manifest")
133+ draft=$(echo "$post_json" | jq -r '.draft')
134+
135+ if [ "$draft" = "true" ]; then
136+ continue
137+ fi
138+
139+ postTitle=$(echo "$post_json" | jq -r '.title')
140+ postSlug=$(echo "$post_json" | jq -r '.slug')
141+ content_json=$(echo "$post_json" | jq -r '.content')
142+ date_json=$(echo "$post_json" | jq -r '.date')
143+ tags_json=$(echo "$post_json" | jq -r '.tags')
144+ dateStr=$(format_date "$date_json")
145+
146+ echo " Post: $postTitle ($postSlug)"
147+
148+ contentFile="$tmpdir/content.txt"
149+ render_content "$content_json" > "$contentFile"
150+
151+ tagsFile="$tmpdir/tags.txt"
152+ render_tags "$tags_json" > "$tagsFile"
153+
154+ echo -n "$siteTitle" > "$tmpdir/siteTitle.txt"
155+ echo -n "$postTitle" > "$tmpdir/postTitle.txt"
156+ echo -n "$dateStr" > "$tmpdir/dateStr.txt"
157+
158+ argsFile="$tmpdir/args.dhall"
159+ cat > "$argsFile" <<DHALL
160+{ siteTitle = $tmpdir/siteTitle.txt as Text
161+, postTitle = $tmpdir/postTitle.txt as Text
162+, dateStr = $tmpdir/dateStr.txt as Text
163+, tagsHtml = $tagsFile as Text
164+, navHtml = $navHtmlFile as Text
165+, contentHtml = $contentFile as Text
166+}
167+DHALL
168+
169+ outDir="$out/posts/$postSlug"
170+ mkdir -p "$outDir"
171+ apply_layout "$layoutsDir/post.dhall" "$argsFile" > "$outDir/index.html"
172+
173+ cat >> "$postsHtmlFile" <<HTML
174+<article class="post-summary">
175+ <h2><a href="/posts/$postSlug/">$postTitle</a></h2>
176+ <time>$dateStr</time>
177+</article>
178+HTML
179+
180+ contentForRss=$(cat "$contentFile")
181+ cat >> "$rssItemsFile" <<XML
182+<item>
183+ <title>$postTitle</title>
184+ <link>$baseUrl/posts/$postSlug/</link>
185+ <guid>$baseUrl/posts/$postSlug/</guid>
186+ <pubDate>$dateStr</pubDate>
187+ <description><![CDATA[$contentForRss]]></description>
188+</item>
189+XML
190+done
191+
192+# --- Step 6: Build index page ---
193+echo "Building index page..."
194+echo -n "$siteTitle" > "$tmpdir/siteTitle.txt"
195+echo -n "$description" > "$tmpdir/description.txt"
196+
197+argsFile="$tmpdir/args.dhall"
198+cat > "$argsFile" <<DHALL
199+{ siteTitle = $tmpdir/siteTitle.txt as Text
200+, description = $tmpdir/description.txt as Text
201+, navHtml = $navHtmlFile as Text
202+, postsHtml = $postsHtmlFile as Text
203+}
204+DHALL
205+
206+apply_layout "$layoutsDir/index.dhall" "$argsFile" > "$out/index.html"
207+
208+# --- Step 7: Build RSS feed ---
209+echo "Building RSS feed..."
210+echo -n "$baseUrl" > "$tmpdir/baseUrl.txt"
211+
212+argsFile="$tmpdir/args.dhall"
213+cat > "$argsFile" <<DHALL
214+{ siteTitle = $tmpdir/siteTitle.txt as Text
215+, baseUrl = $tmpdir/baseUrl.txt as Text
216+, description = $tmpdir/description.txt as Text
217+, itemsXml = $rssItemsFile as Text
218+}
219+DHALL
220+
221+apply_layout "$layoutsDir/rss.dhall" "$argsFile" > "$out/rss.xml"
222+
223+# --- Step 8: Copy theme ---
224+echo "Copying theme..."
225+cp "$themeDir/style.css" "$out/style.css"
226+
227+echo "Build complete!"
resultnew file+1
@@ -0,0 +1 @@
1+/nix/store/iyhmcxwzcckwkg1n30h26lvjhvwvcifh-static-dhall-site
templates/default/content/about.mdnew file+5
@@ -0,0 +1,5 @@
1+Welcome to my site! This is the about page.
2+
3+## About Me
4+
5+Write something about yourself here.
templates/default/content/posts/hello-world.mdnew file+21
@@ -0,0 +1,21 @@
1+# Hello World
2+
3+This is my first blog post, built with [static-dhall](https://github.com/ilyakooo0/static-dhall).
4+
5+## What is static-dhall?
6+
7+A static site generator that uses:
8+
9+- **Dhall** for type-safe site configuration
10+- **Markdown** for content authoring
11+- **Nix** for reproducible builds
12+
13+## Getting Started
14+
15+Edit `site.dhall` to configure your site, then run:
16+
17+```bash
18+nix build
19+```
20+
21+Your site will be in `./result/`.
templates/default/flake.nixnew file+17
@@ -0,0 +1,17 @@
1+{
2+ description = "My static-dhall site";
3+
4+ inputs = {
5+ static-dhall.url = "github:ilyakooo0/static-dhall";
6+ };
7+
8+ outputs = { self, static-dhall }:
9+ let
10+ system = "x86_64-linux";
11+ in
12+ {
13+ packages.${system}.default = static-dhall.lib.${system}.buildSite {
14+ src = ./.;
15+ };
16+ };
17+}
templates/default/site.dhallnew file+28
@@ -0,0 +1,28 @@
1+let SD = ./.static-dhall/package.dhall
2+
3+in SD.Site::{
4+ , title = "My Site"
5+ , baseUrl = "https://example.com"
6+ , author = "Your Name"
7+ , description = "A site built with static-dhall"
8+ , nav =
9+ [ { label = "Home", url = "/" }
10+ , { label = "About", url = "/about" }
11+ ]
12+ , pages =
13+ [ SD.Page::{
14+ , title = "About"
15+ , slug = "about"
16+ , content = SD.Content.File "content/about.md"
17+ }
18+ ]
19+ , posts =
20+ [ SD.Post::{
21+ , title = "Hello World"
22+ , slug = "hello-world"
23+ , content = SD.Content.File "content/posts/hello-world.md"
24+ , date = { year = 2026, month = 1, day = 15 }
25+ , tags = [ "meta" ]
26+ }
27+ ]
28+ }
theme/style.cssnew file+188
@@ -0,0 +1,188 @@
1+*,
2+*::before,
3+*::after {
4+ box-sizing: border-box;
5+ margin: 0;
6+ padding: 0;
7+}
8+
9+:root {
10+ --font-body: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, sans-serif;
11+ --font-mono: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
12+ --color-bg: #fff;
13+ --color-text: #1a1a1a;
14+ --color-muted: #666;
15+ --color-accent: #0055aa;
16+ --color-border: #e0e0e0;
17+ --color-code-bg: #f5f5f5;
18+ --max-width: 42rem;
19+}
20+
21+@media (prefers-color-scheme: dark) {
22+ :root {
23+ --color-bg: #1a1a1a;
24+ --color-text: #e0e0e0;
25+ --color-muted: #999;
26+ --color-accent: #6db3f2;
27+ --color-border: #333;
28+ --color-code-bg: #2a2a2a;
29+ }
30+}
31+
32+html {
33+ font-size: 18px;
34+ line-height: 1.6;
35+}
36+
37+body {
38+ font-family: var(--font-body);
39+ color: var(--color-text);
40+ background: var(--color-bg);
41+ max-width: var(--max-width);
42+ margin: 0 auto;
43+ padding: 2rem 1rem;
44+}
45+
46+a {
47+ color: var(--color-accent);
48+ text-decoration: none;
49+}
50+
51+a:hover {
52+ text-decoration: underline;
53+}
54+
55+nav {
56+ margin-bottom: 2rem;
57+ padding-bottom: 1rem;
58+ border-bottom: 1px solid var(--color-border);
59+}
60+
61+nav a {
62+ margin-right: 1rem;
63+ font-weight: 500;
64+}
65+
66+.site-header {
67+ margin-bottom: 2rem;
68+}
69+
70+.site-header h1 {
71+ margin-bottom: 0.25rem;
72+}
73+
74+.site-header p {
75+ color: var(--color-muted);
76+}
77+
78+article header {
79+ margin-bottom: 1.5rem;
80+}
81+
82+article header h1 {
83+ margin-bottom: 0.25rem;
84+}
85+
86+article header time {
87+ color: var(--color-muted);
88+ font-size: 0.9rem;
89+}
90+
91+h1, h2, h3, h4 {
92+ line-height: 1.3;
93+ margin-top: 1.5em;
94+ margin-bottom: 0.5em;
95+}
96+
97+h1 { font-size: 1.8rem; }
98+h2 { font-size: 1.4rem; }
99+h3 { font-size: 1.15rem; }
100+
101+p, ul, ol, blockquote, pre {
102+ margin-bottom: 1rem;
103+}
104+
105+ul, ol {
106+ padding-left: 1.5rem;
107+}
108+
109+blockquote {
110+ border-left: 3px solid var(--color-border);
111+ padding-left: 1rem;
112+ color: var(--color-muted);
113+}
114+
115+code {
116+ font-family: var(--font-mono);
117+ font-size: 0.85em;
118+ background: var(--color-code-bg);
119+ padding: 0.15em 0.3em;
120+ border-radius: 3px;
121+}
122+
123+pre {
124+ background: var(--color-code-bg);
125+ padding: 1rem;
126+ border-radius: 5px;
127+ overflow-x: auto;
128+}
129+
130+pre code {
131+ background: none;
132+ padding: 0;
133+}
134+
135+img {
136+ max-width: 100%;
137+ height: auto;
138+}
139+
140+hr {
141+ border: none;
142+ border-top: 1px solid var(--color-border);
143+ margin: 2rem 0;
144+}
145+
146+.tags {
147+ list-style: none;
148+ display: flex;
149+ gap: 0.5rem;
150+ padding: 0;
151+ margin-top: 0.5rem;
152+}
153+
154+.tags li {
155+ font-size: 0.8rem;
156+ color: var(--color-muted);
157+ background: var(--color-code-bg);
158+ padding: 0.1em 0.5em;
159+ border-radius: 3px;
160+}
161+
162+.post-list article {
163+ margin-bottom: 1.5rem;
164+}
165+
166+.post-list h2 {
167+ margin-top: 0;
168+ margin-bottom: 0.15rem;
169+ font-size: 1.2rem;
170+}
171+
172+.post-list time {
173+ color: var(--color-muted);
174+ font-size: 0.85rem;
175+}
176+
177+.post-summary {
178+ padding-bottom: 1rem;
179+ border-bottom: 1px solid var(--color-border);
180+}
181+
182+footer {
183+ margin-top: 3rem;
184+ padding-top: 1rem;
185+ border-top: 1px solid var(--color-border);
186+ color: var(--color-muted);
187+ font-size: 0.85rem;
188+}