diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
index adfe02e..79e7f6f 100644
--- a/.github/workflows/pages.yml
+++ b/.github/workflows/pages.yml
@@ -20,7 +20,7 @@ jobs:
env:
HUGO_VERSION: 0.154.0
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@v6
with:
submodules: recursive
fetch-depth: 0
@@ -32,9 +32,9 @@ jobs:
extended: true
- name: Setup Node
- uses: actions/setup-node@v4
+ uses: actions/setup-node@v6
with:
- node-version: 20
+ node-version: 22
cache: npm
- name: Install dependencies
@@ -53,7 +53,7 @@ jobs:
fi
- name: Upload artifact
- uses: actions/upload-pages-artifact@v3
+ uses: actions/upload-pages-artifact@v5
with:
path: exampleSite/public
@@ -65,4 +65,4 @@ jobs:
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
- uses: actions/deploy-pages@v4
+ uses: actions/deploy-pages@v5
diff --git a/exampleSite/content/post/2026/05/07/sample/index.md b/exampleSite/content/post/2026/05/07/sample/index.md
new file mode 100644
index 0000000..0436673
--- /dev/null
+++ b/exampleSite/content/post/2026/05/07/sample/index.md
@@ -0,0 +1,23 @@
+---
+title: "Mẫu bài viết đầu tiên"
+date: 2026-05-07T19:00:00+07:00
+draft: false
+tags: ["hugo", "tsuki", "demo"]
+categories: ["demo"]
+description: "Bài viết mẫu cho tsuki theme."
+---
+
+Đây là một bài viết mẫu để kiểm tra layout của tsuki.
+
+## Heading thứ hai
+
+Một đoạn văn ngắn với **chữ in đậm** và *chữ nghiêng* và `mã inline`.
+
+```python
+def hello():
+ print("Xin chào, tsuki!")
+```
+
+- Mục một
+- Mục hai
+- Mục ba
diff --git a/layouts/404.html b/layouts/404.html
new file mode 100644
index 0000000..2d57e4a
--- /dev/null
+++ b/layouts/404.html
@@ -0,0 +1,9 @@
+{{ define "body_class" }}error-page{{ end }}
+
+{{ define "main" }}
+
+{{ end }}
diff --git a/layouts/_partials/.gitkeep b/layouts/_partials/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/layouts/_partials/footer.html b/layouts/_partials/footer.html
new file mode 100644
index 0000000..4fa206d
--- /dev/null
+++ b/layouts/_partials/footer.html
@@ -0,0 +1,11 @@
+
diff --git a/layouts/_partials/head.html b/layouts/_partials/head.html
new file mode 100644
index 0000000..c5e357e
--- /dev/null
+++ b/layouts/_partials/head.html
@@ -0,0 +1,68 @@
+{{- $title := cond .IsHome site.Title (printf "%s · %s" .Title site.Title) -}}
+{{- $description := .Description | default .Summary | default site.Params.description | default site.Title -}}
+{{- $ogImage := .Params.image | default site.Params.profile.avatar -}}
+
+
+
+
+
+
{{ $title }}
+
+
+
+{{/* Theme flash prevention — must run before */}}
+
+
+{{/* OpenGraph */}}
+
+
+
+
+
+{{- with $ogImage }}
+
+{{- end }}
+{{- if and .IsPage .Date }}
+
+{{- with .Lastmod }}
+
+{{- end }}
+{{- end }}
+
+{{/* Twitter Card */}}
+
+
+
+{{- with $ogImage }}
+
+{{- end }}
+
+{{/* RSS autodiscovery */}}
+{{- with .OutputFormats.Get "RSS" }}
+
+{{- end }}
+
+{{/* Pagination prev/next for SEO — only on paginated kinds */}}
+{{- if or .IsHome (eq .Kind "section") (eq .Kind "taxonomy") (eq .Kind "term") }}
+ {{- with .Paginator }}
+ {{- if .HasPrev }}{{ end }}
+ {{- if .HasNext }}{{ end }}
+ {{- end }}
+{{- end }}
+
+{{/* Favicon */}}
+
+
+
+{{/* Theme CSS — placeholder; Phase 6 wires resources.Get */}}
+{{/* {{ $css := resources.Get "css/tsuki.css" | minify | fingerprint }}
+ */}}
diff --git a/layouts/_partials/header.html b/layouts/_partials/header.html
new file mode 100644
index 0000000..2a03529
--- /dev/null
+++ b/layouts/_partials/header.html
@@ -0,0 +1,9 @@
+
diff --git a/layouts/_partials/home/.gitkeep b/layouts/_partials/home/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/layouts/_partials/icon.html b/layouts/_partials/icon.html
new file mode 100644
index 0000000..cd036ff
--- /dev/null
+++ b/layouts/_partials/icon.html
@@ -0,0 +1,4 @@
+{{- $name := . -}}
+{{- with resources.Get (printf "icons/%s.svg" $name) -}}
+{{ .Content | safeHTML }}
+{{- end -}}
diff --git a/layouts/_partials/meta.html b/layouts/_partials/meta.html
new file mode 100644
index 0000000..8ad2c80
--- /dev/null
+++ b/layouts/_partials/meta.html
@@ -0,0 +1,20 @@
+
+ {{- with .Date }}
+
+ {{- end }}
+ {{- if gt .ReadingTime 0 }}
+
+ {{ i18n "readingTime" (dict "Count" .ReadingTime) | default (printf "%d min" .ReadingTime) }}
+
+ {{- end }}
+ {{- with .Params.tags }}
+
+ {{- range $i, $tag := . -}}
+ {{- if $i }}, {{ end -}}
+ #{{ $tag }}
+ {{- end -}}
+
+ {{- end }}
+
diff --git a/layouts/_partials/nav.html b/layouts/_partials/nav.html
new file mode 100644
index 0000000..a46b7b9
--- /dev/null
+++ b/layouts/_partials/nav.html
@@ -0,0 +1,10 @@
+
diff --git a/layouts/_partials/post-card.html b/layouts/_partials/post-card.html
new file mode 100644
index 0000000..cb1bbc7
--- /dev/null
+++ b/layouts/_partials/post-card.html
@@ -0,0 +1,14 @@
+{{- $page := . -}}
+
+
+ {{- with $page.Date }}
+
+ {{- end }}
+ {{- with ($page.Summary | plainify) }}
+ {{ . | truncate 180 }}
+ {{- end }}
+
diff --git a/layouts/baseof.html b/layouts/baseof.html
new file mode 100644
index 0000000..7cc237f
--- /dev/null
+++ b/layouts/baseof.html
@@ -0,0 +1,15 @@
+
+
+
+ {{ partial "head.html" . }}
+ {{ block "head_extra" . }}{{ end }}
+
+
+ {{ partial "header.html" . }}
+
+ {{ block "main" . }}{{ end }}
+
+ {{ partial "footer.html" . }}
+ {{ block "scripts" . }}{{ end }}
+
+
diff --git a/layouts/home.html b/layouts/home.html
new file mode 100644
index 0000000..312ad17
--- /dev/null
+++ b/layouts/home.html
@@ -0,0 +1,9 @@
+{{ define "body_class" }}home{{ end }}
+
+{{ define "main" }}
+{{/* Phase 4 fills hero/projects/recent-posts here. Placeholder for now. */}}
+
+ {{ site.Title }}
+ {{- with site.Params.description }}{{ . }}
{{ end }}
+
+{{ end }}
diff --git a/layouts/list.html b/layouts/list.html
new file mode 100644
index 0000000..80d27e3
--- /dev/null
+++ b/layouts/list.html
@@ -0,0 +1,14 @@
+{{ define "body_class" }}list{{ end }}
+
+{{ define "main" }}
+
+
+
+ {{- range .Pages }}
+ {{ partial "post-card.html" . }}
+ {{- end }}
+
+{{ end }}
diff --git a/layouts/single.html b/layouts/single.html
new file mode 100644
index 0000000..fc2baa5
--- /dev/null
+++ b/layouts/single.html
@@ -0,0 +1,27 @@
+{{ define "body_class" }}post{{ end }}
+
+{{ define "main" }}
+
+
+
+
+ {{ .Content }}
+
+
+
+
+{{ end }}