diff --git a/.gitignore b/.gitignore
index e63012d..2dfe775 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
 .qlot
-public/dist.css
 bin/tailwindcss
+public/style/dist.css
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..90353a2
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,25 @@
+FROM fukamachi/qlot
+
+# 作業ディレクトリ
+WORKDIR /app
+
+# ソース全体をコピー
+COPY . /app
+
+# Tailwind CLI をダウンロード&インストール
+RUN mkdir -p ./bin \
+  && curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64 \
+  && chmod +x tailwindcss-linux-x64 \
+  && mv tailwindcss-linux-x64 ./bin/tailwindcss
+
+# Tailwind CSS をビルド(global.css -> dist.css)
+RUN ./bin/tailwindcss -i ./public/style/global.css -o ./public/style/dist.css --minify
+
+# Qlot依存関係のインストール
+RUN qlot install
+
+# ポート開放
+EXPOSE 3000
+
+# アプリ起動
+CMD [".qlot/bin/clackup", "--system", "hp", "--server", "woo", "--port", "3000", "src/app.lisp"]
diff --git a/Makefile b/Makefile
index 9e820ae..b5ba028 100644
--- a/Makefile
+++ b/Makefile
@@ -2,8 +2,8 @@ TAILWIND_URL=https://github.com/tailwindlabs/tailwindcss/releases/latest/downloa
 TAILWIND_TARGET=tailwindcss-macos-arm64
 BIN_DIR=./bin
 TAILWIND_BIN=$(BIN_DIR)/tailwindcss
-STYLE_SRC=./public/style.css
-STYLE_DIST=./public/dist.css
+STYLE_SRC=./public/style/global.css
+STYLE_DIST=./public/style/dist.css
 
 all: install
 
@@ -40,4 +40,10 @@ lem: ## Open Lem with TailwindCSS server
 	WATCH_PID=$$!; \
 	trap "kill $$WATCH_PID" SIGINT SIGTERM EXIT; \
 	lem; \
-	kill $$WATCH_PID
\ No newline at end of file
+	kill $$WATCH_PID
+
+docker-build:
+	docker build -t hp .
+
+docker-run:
+	docker run -p 3000:3000 hp
\ No newline at end of file
diff --git a/README.md b/README.md
index 66efaf1..e245afd 100644
--- a/README.md
+++ b/README.md
@@ -1 +1 @@
-# homepage (WIP)
+# hp
diff --git a/public/favicon.ico b/public/favicon.ico
deleted file mode 100644
index 60cabc0..0000000
Binary files a/public/favicon.ico and /dev/null differ
diff --git a/public/fv.jpg b/public/fv.jpg
deleted file mode 100644
index ca68e44..0000000
Binary files a/public/fv.jpg and /dev/null differ
diff --git a/public/img/favicon.ico b/public/img/favicon.ico
new file mode 100644
index 0000000..4dc7866
Binary files /dev/null and b/public/img/favicon.ico differ
diff --git a/public/img/me.jpg b/public/img/me.jpg
new file mode 100644
index 0000000..e78e422
Binary files /dev/null and b/public/img/me.jpg differ
diff --git a/public/logo.png b/public/logo.png
deleted file mode 100644
index 75a0ef9..0000000
Binary files a/public/logo.png and /dev/null differ
diff --git a/public/style.css b/public/style/global.css
similarity index 100%
rename from public/style.css
rename to public/style/global.css
diff --git a/qlfile b/qlfile
index 70b08f9..5baf28a 100644
--- a/qlfile
+++ b/qlfile
@@ -2,8 +2,10 @@ ql fiveam
 ql cl-jingle
 git hsx https://github.com/skyizwhite/hsx.git
 git ningle-fbr https://github.com/skyizwhite/ningle-fbr.git
+git lack-mw https://github.com/skyizwhite/lack-mw.git
 ql cl-ppcre
 ql trivial-backtrace
 ql trivia
 ql cl-str
 ql quri
+ql clack
diff --git a/qlfile.lock b/qlfile.lock
index 4625fbc..4b4d73b 100644
--- a/qlfile.lock
+++ b/qlfile.lock
@@ -1,11 +1,11 @@
 ("quicklisp" .
  (:class qlot/source/dist:source-dist
   :initargs (:distribution "https://beta.quicklisp.org/dist/quicklisp.txt" :%version :latest)
-  :version "2023-10-21"))
+  :version "2024-10-12"))
 ("fiveam" .
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
-  :version "ql-2023-10-21"))
+  :version "ql-2024-10-12"))
 ("cl-jingle" .
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
@@ -13,19 +13,23 @@
 ("hsx" .
  (:class qlot/source/git:source-git
   :initargs (:remote-url "https://github.com/skyizwhite/hsx.git")
-  :version "git-f60259ec4a101de87c5364c3f1b571706448d3a0"))
+  :version "git-4ff1c97e3ff727aa332995f5be4dcfb138a45d5f"))
 ("ningle-fbr" .
  (:class qlot/source/git:source-git
   :initargs (:remote-url "https://github.com/skyizwhite/ningle-fbr.git")
-  :version "git-d20dbe264911b7dfd6e6fade899db9b09bd2dd32"))
+  :version "git-bc87e5de01959cd99364bc14ad3eaf88e52e4478"))
+("lack-mw" .
+ (:class qlot/source/git:source-git
+  :initargs (:remote-url "https://github.com/skyizwhite/lack-mw.git")
+  :version "git-77a0f436635e5beadaba3765492832704a015a3c"))
 ("cl-ppcre" .
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
-  :version "ql-2023-10-21"))
+  :version "ql-2024-10-12"))
 ("trivial-backtrace" .
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
-  :version "ql-2023-10-21"))
+  :version "ql-2023-02-14"))
 ("trivia" .
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
@@ -38,3 +42,7 @@
  (:class qlot/source/ql:source-ql
   :initargs (:%version :latest)
   :version "ql-2024-10-12"))
+("clack" .
+ (:class qlot/source/ql:source-ql
+  :initargs (:%version :latest)
+  :version "ql-2024-10-12"))
diff --git a/src/app.lisp b/src/app.lisp
index 6465f44..07bebf9 100644
--- a/src/app.lisp
+++ b/src/app.lisp
@@ -20,3 +20,5 @@
 (jg:install-middleware *app* *recoverer*)
 (jg:install-middleware *app* *trim-trailing-slash*)
 (jg:install-middleware *app* *public-server*)
+
+(jg:configure *app*)
diff --git a/src/components/footer.lisp b/src/components/footer.lisp
deleted file mode 100644
index bac89ba..0000000
--- a/src/components/footer.lisp
+++ /dev/null
@@ -1,11 +0,0 @@
-(defpackage #:hp/components/footer
-  (:use #:cl
-       #:hsx)
-  (:export #:~footer))
-(in-package #:hp/components/footer)
-
-(defcomp ~footer ()
-  (hsx
-   (footer :class "fixed bottom-0 w-full"
-     (div :class "container py-6 flex justify-end"
-       (p "© 2025 skyizwhite")))))
\ No newline at end of file
diff --git a/src/components/header.lisp b/src/components/header.lisp
deleted file mode 100644
index 7af6768..0000000
--- a/src/components/header.lisp
+++ /dev/null
@@ -1,27 +0,0 @@
-(defpackage #:hp/components/header
-  (:use #:cl
-        #:hsx)
-  (:export #:~header))
-(in-package #:hp/components/header)
-
-(defcomp ~header ()
-  (let ((links '(("Home" "/")
-                 ("About" "/about")
-                 ("Work" "/work")
-                 ("Article" "/article")
-                 ("Contact" "/contact"))))
-    (hsx
-     (header :class "fixed top-0 w-full"
-       (div :class "container flex justify-between py-6"
-         (h1
-           (a :href "/"
-             (img
-               :src "/logo.png" :alt "Amongtellers"
-               :class "w-52 h-auto")))
-         (ul :class "flex flex-col gap-4"
-           (loop
-             :for (title href) :in links :collect
-                (hsx
-                 (li :class "flex items-center"
-                   (a :href href :class "text-lg hover:text-orange-600"
-                     title))))))))))
diff --git a/src/main.lisp b/src/main.lisp
index c83f1f6..17327df 100644
--- a/src/main.lisp
+++ b/src/main.lisp
@@ -11,10 +11,7 @@
 (in-package #:hp)
 
 (defun start ()
-  (jg:start *app*)
-  (when (env:dev-mode-p)
-    (uiop:run-program (format nil "open http://~a:~a"
-                              env:*address* env:*port*))))
+  (jg:start *app*))
 
 (defun stop ()
   (jg:stop *app*))
diff --git a/src/renderer.lisp b/src/renderer.lisp
index 05f127d..4f5623d 100644
--- a/src/renderer.lisp
+++ b/src/renderer.lisp
@@ -2,54 +2,73 @@
   (:use #:cl
         #:hsx
         #:trivia)
-  (:import-from #:str)
   (:local-nicknames (#:jg #:jingle))
   (:import-from #:hsx/element
                 #:element)
-  (:local-nicknames (#:env #:hp/env))
-  (:import-from #:hp/components/header
-                #:~header)
-  (:import-from #:hp/components/footer
-                #:~footer))
+  (:local-nicknames (#:env #:hp/env)))
 (in-package #:hp/renderer)
 
 (defun bust-cache (url)
-  (format nil "~a?~a" url #.(get-universal-time)))
+  (format nil "~a?v=~a" url (get-universal-time)))
 
-(defcomp ~document (&key title description children)
+(defparameter *metadata-template*
+  (list :title (lambda (title)
+                 (format nil "~@[~a - ~]~a" title "skyizwhite.dev"))
+        :description "The personal homepage of Akira Tempaku (paku) - projects, thoughts, and more."
+        :og-url "https://skyizwhite.dev"
+        :og-type "website"
+        :og-image (lambda (path)
+                    (format nil "https://skyizwhite.dev~@[~a~]" path))
+        :og-image-width 1024
+        :og-image-height 1024))
+
+(defun complete-metadata (metadata)
+  (loop 
+    :for (key template) :on *metadata-template* by #'cddr
+    :for value := (getf metadata key)
+    :append (list key (if (functionp template)
+                          (funcall template value)
+                          (or value template)))))
+
+(defcomp ~document (&key title
+                         description
+                         og-url
+                         og-type
+                         og-image
+                         og-image-width
+                         og-image-height
+                         children)
   (hsx
    (html :lang "ja"
      (head
        (meta :charset "UTF-8")
        (meta :name "viewport" :content "width=device-width, initial-scale=1")
-       (link :rel "icon" :href (bust-cache "/favicon.ico"))
-       (link :rel "apple-touch-icon" :href (bust-cache "/favicon.ico"))
-       (link :rel "stylesheet" :href (bust-cache "/dist.css"))
+       (title title)
+       (meta :name "description" :content description)
+       (meta :property "og:title" :content title)
+       (meta :property "og:description" :content description)
+       (meta :property "og:url" :content og-url)
+       (meta :property "og:type" :content og-type)
+       (meta :property "og:site_name" :content "skyizwhite.dev")
+       (meta :property "og:image" :content og-image)
+       (meta :property "og:image:width" :content og-image-width)
+       (meta :property "og:image:height" :content og-image-height)
+       (link :rel "icon" :type "image/x-icon" :href "/img/favicon.ico")
+       (link :rel "apple-touch-icon" :href "/img/favicon.ico")
+       (link :rel "stylesheet" :href (bust-cache "/style/dist.css"))
        (link :rel "preconnect" :href "https://fonts.googleapis.com")
        (link :rel "preconnect" :href "https://fonts.gstatic.com" :crossorigin t)
        (link :rel "stylesheet" :href "https://fonts.googleapis.com/css2?family=Noto+Sans+JP&display=swap")
        (script :src "https://cdn.jsdelivr.net/npm/htmx.org@2.0.0/dist/htmx.min.js")
        (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-head-support@2.0.0/head-support.min.js")
        (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.0/response-targets.min.js")
-       (script :src "https://cdn.jsdelivr.net/npm/alpinejs@3.14.0/dist/cdn.min.js" :defer t)
-       (title (format nil "~@[~a - ~]Amongtellers" title))
-       (meta
-         :name "description"
-         :content
-         (or description
-             (hsx
-              (<>
-                "Welcome to the official website of 'Amongtellers (Amaterasu)', "
-                "a personal project by paku (skyizwhite). "
-                "Discover project details, the latest updates, and related activities.")))))
+       (script :src "https://cdn.jsdelivr.net/npm/alpinejs@3.14.0/dist/cdn.min.js" :defer t))
      (body
        :hx-ext "head-support, response-targets"
        :hx-boost "true" :hx-target-404 "body" :hx-target-5* "body"
        :class "h-[100svh] flex flex-col"
-       (~header)
        (main :class "flex-1 h-full"
-         children)
-       (~footer)))))
+         children)))))
 
 (defmethod jg:process-response ((app jg:app) result)
   (jg:set-response-header :content-type "text/html; charset=utf-8")
@@ -63,5 +82,6 @@
                        ((guard (or (list element metadata)
                                    element)
                                (typep element 'element))
-                        (~document metadata element))
+                        (~document (complete-metadata metadata)
+                          element))
                        (_ (error "Invalid response form"))))))
diff --git a/src/routes/index.lisp b/src/routes/index.lisp
index 95f7371..0ef2dd5 100644
--- a/src/routes/index.lisp
+++ b/src/routes/index.lisp
@@ -4,18 +4,28 @@
   (:export #:handle-get))
 (in-package #:hp/routes/index)
 
+(defparameter *links*
+  '(("Keyoxide"       "https://keyoxide.org/f39d5b2c951d16732a5cd3528f0c1a22f26d7e62")
+    ("GitHub"         "https://github.com/skyizwhite")
+    ("Forgejo"        "https://code.skyizwhite.dev/paku")
+    ("X"              "https://x.com/skyizwhite")
+    ("Fediverse"      "https://himagine.club/@skyizwhite")
+    ("Service Status" "https://status.skyizwhite.dev")))
+
 (defcomp ~page ()
   (hsx
-   (section
-     ; first view
-     (div :class "h-[100svh] bg-[url('/fv.jpg')] bg-cover bg-center flex"
-       (div :class "container flex items-end justify-between"
-         (h1 :class "flex flex-col text-6xl font-bold italic leading-normal pb-10"
-           (span :class "block"
-             "Beyond Differences,")
-           (span :class "block"
-             "Shaping Tomorrow")))))))
-
+   (section :class "flex flex-col items-center justify-center h-full"
+     (img :src "/img/me.jpg" :alt "Profile Picture" :class "size-40 rounded rounded-full border shadow-lg")
+     (div :class "flex flex-col items-center gap-2 py-6"
+       (h1 :class "font-bold text-2xl"
+         "Akira Tempaku")
+       (p :class "text-xl"
+         "Web developer"))
+     (div :class "flex flex-col items-center text-pink-500"
+       (loop
+         :for (name url) :in *links*
+         :collect (hsx (a :href url :target "_blank" :class "text-lg hover:underline"
+                         name)))))))
 (defun handle-get (params)
   (declare (ignore params))
   (~page))
diff --git a/src/routes/not-found.lisp b/src/routes/not-found.lisp
index 97b0750..f1301af 100644
--- a/src/routes/not-found.lisp
+++ b/src/routes/not-found.lisp
@@ -11,12 +11,8 @@
 
 (defcomp ~page ()
   (hsx
-   (section :class "container flex flex-col justify-center items-center h-full gap-10"
-     (h1 :class "text-2xl text-red-600"
-       (getf *metadata* :title))
-     (p (getf *metadata* :description))
-     (a :href "/" :class "text-orange-600"
-       "Return to the homepage"))))
+   (section
+     (h1 "404 Not Found"))))
 
 (defun handle-not-found ()
   (jg:set-response-status :not-found)