diff --git a/src/lib/metadata.lisp b/src/lib/metadata.lisp
new file mode 100644
index 0000000..201bd52
--- /dev/null
+++ b/src/lib/metadata.lisp
@@ -0,0 +1,29 @@
+(defpackage #:hp/lib/metadata
+  (:use #:cl)
+  (:import-from #:hp/lib/env
+                #:hp-url)
+  (:export #:complete-metadata))
+(in-package #:hp/lib/metadata)
+
+(defun path->url (path)
+  (concatenate 'string
+               (hp-url)
+               (and (not (string= path "/")) path)))
+
+(defparameter *metadata-template*
+  (list :title (lambda (title) (format nil "~@[~a - ~]~a" title "skyizwhite.dev"))
+        :description "The personal website of Akira Tempaku (paku) - projects, thoughts, and more."
+        :canonical #'path->url
+        :og-url #'path->url
+        :og-type "website"
+        :og-image (path->url "/img/og.jpg")
+        :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)))))
diff --git a/src/renderer.lisp b/src/renderer.lisp
index 3c7c496..b34f83f 100644
--- a/src/renderer.lisp
+++ b/src/renderer.lisp
@@ -8,91 +8,24 @@
                 #:element)
   (:import-from #:hp/lib/env
                 #:hp-url
-                #:hp-env))
+                #:hp-env)
+  (:import-from #:hp/lib/metadata
+                #:complete-metadata)
+  (:import-from #:hp/ui/layout
+                #:~layout))
 (in-package #:hp/renderer)
 
-(defun path->url (path)
-  (concatenate 'string
-               (hp-url)
-               (and (not (string= path "/")) path)))
-
-(defparameter *metadata-template*
-  (list :title (lambda (title) (format nil "~@[~a - ~]~a" title "skyizwhite.dev"))
-        :description "The personal website of Akira Tempaku (paku) - projects, thoughts, and more."
-        :canonical #'path->url
-        :og-url #'path->url
-        :og-type "website"
-        :og-image (path->url "/img/og.jpg")
-        :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)))))
-
-(defun bust-cache (url)
-  (format nil "~a?v=~a" url #.(get-universal-time)))
-
-(defcomp ~document (&key title
-                         description
-                         canonical
-                         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")
-       (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 "canonical" :href canonical)
-       (link :rel "icon" :type "image/png" :href "/img/favicon-96x96.png" :sizes "96x96")
-       (link :rel "icon" :type "image/svg+xml" :href "/img/favicon.svg")
-       (link :rel "shortcut icon" :href "/img/favicon.ico")
-       (link :rel "apple-touch-icon" :sizes "180x180" :href "/img/apple-touch-icon.png")
-       (meta :name "apple-mobile-web-app-title" :content "skyizwhite")
-       (link :rel "manifest" :href "/img/site.webmanifest")
-       (link :rel "stylesheet" :href (bust-cache "/style/dist.css"))
-       (link :rel "preconnect" :href "https://api.fonts.coollabs.io")
-       (link :rel "stylesheet" :href "https://api.fonts.coollabs.io/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))
-     (body
-       :hx-ext "head-support, response-targets"
-       :hx-boost "true" :hx-target-404 "body" :hx-target-5* "body"
-       :class "h-[100svh] flex flex-col"
-       (main :class "flex-1 h-full"
-         children)))))
-
 (defmethod jingle:process-response ((app jingle:app) result)
   (set-response-header :content-type "text/html; charset=utf-8")
   (set-response-header :cache-control (if (string= (hp-env) "dev")
-                                          "private, no-store, no-cache, must-revalidate"
-                                          "public, max-age=60, s-maxage=300, stale-while-revalidate=300, stale-if-error=300"))
+                                          "private, no-store"
+                                          "public, s-maxage=60, stale-while-revalidate=86400, stale-if-error=86400"))
   (call-next-method app
                     (hsx:render-to-string
                      (match result
                        ((guard (or (list page metadata)
                                    page)
                                (typep page 'element))
-                        (~document (complete-metadata metadata)
+                        (~layout (complete-metadata metadata)
                           page))
                        (_ (error "Invalid response form"))))))
diff --git a/src/routes/bio.lisp b/src/routes/bio.lisp
new file mode 100644
index 0000000..71e5411
--- /dev/null
+++ b/src/routes/bio.lisp
@@ -0,0 +1,17 @@
+(defpackage #:hp/routes/bio
+  (:use #:cl
+        #:hsx)
+  (:export #:handle-get))
+(in-package :hp/routes/bio)
+
+(defparameter *metadata*
+  (list :title "bio"))
+
+(defcomp ~page ()
+  (hsx
+   (section
+     (p "Coming soon..."))))
+
+(defun handle-get (params)
+  (declare (ignore params))
+  (list (~page) *metadata*))
diff --git a/src/routes/blog.lisp b/src/routes/blog.lisp
new file mode 100644
index 0000000..7c13289
--- /dev/null
+++ b/src/routes/blog.lisp
@@ -0,0 +1,17 @@
+(defpackage #:hp/routes/blog
+  (:use #:cl
+        #:hsx)
+  (:export #:handle-get))
+(in-package :hp/routes/blog)
+
+(defparameter *metadata*
+  (list :title "blog"))
+
+(defcomp ~page ()
+  (hsx
+   (section
+     (p "Coming soon..."))))
+
+(defun handle-get (params)
+  (declare (ignore params))
+  (list (~page) *metadata*))
diff --git a/src/routes/index.lisp b/src/routes/index.lisp
index 8cf6c73..11fd0dc 100644
--- a/src/routes/index.lisp
+++ b/src/routes/index.lisp
@@ -14,16 +14,16 @@
 (defcomp ~page ()
   (hsx
    (section :class "flex flex-col items-center justify-center h-full"
-     (img :src "/img/me.webp" :alt "Profile Picture" :class "size-40 rounded rounded-full border shadow-lg")
+     (img :src "/img/avatar.jpg" :alt "avatar" :class "size-40 rounded-xl shadow-sm")
      (div :class "flex flex-col items-center gap-2 py-6"
-       (h1 :class "font-bold text-2xl"
+       (h1 :class "font-bold text-2xl text-center"
          "Akira Tempaku")
        (p :class "text-xl"
          "Web developer"))
-     (div :class "flex flex-col items-center text-pink-500"
+     (div :class "flex flex-col items-center"
        (loop
          :for (name url) :in *links*
-         :collect (hsx (a :href url :target "_blank" :class "text-lg hover:underline"
+         :collect (hsx (a :href url :target "_blank" :class "text-lg underline hover:text-pink-500"
                          name)))))))
 
 (defun handle-get (params)
diff --git a/src/routes/work.lisp b/src/routes/work.lisp
new file mode 100644
index 0000000..fa96819
--- /dev/null
+++ b/src/routes/work.lisp
@@ -0,0 +1,17 @@
+(defpackage #:hp/routes/work
+  (:use #:cl
+        #:hsx)
+  (:export #:handle-get))
+(in-package :hp/routes/work)
+
+(defparameter *metadata*
+  (list :title "work"))
+
+(defcomp ~page ()
+  (hsx
+   (section
+     (p "Coming soon..."))))
+
+(defun handle-get (params)
+  (declare (ignore params))
+  (list (~page) *metadata*))
diff --git a/src/ui/layout.lisp b/src/ui/layout.lisp
new file mode 100644
index 0000000..23785b5
--- /dev/null
+++ b/src/ui/layout.lisp
@@ -0,0 +1,70 @@
+(defpackage #:hp/ui/layout
+  (:use #:cl
+        #:hsx)
+  (:export #:~layout))
+(in-package #:hp/ui/layout)
+
+(defun bust-cache (url)
+  (format nil "~a?v=~a" url #.(get-universal-time)))
+
+(defcomp ~layout (&key title
+                       description
+                       canonical
+                       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")
+       (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 "canonical" :href canonical)
+       (link :rel "icon" :type "image/png" :href "/img/favicon-96x96.png" :sizes "96x96")
+       (link :rel "icon" :type "image/svg+xml" :href "/img/favicon.svg")
+       (link :rel "shortcut icon" :href "/img/favicon.ico")
+       (link :rel "apple-touch-icon" :sizes "180x180" :href "/img/apple-touch-icon.png")
+       (meta :name "apple-mobile-web-app-title" :content "skyizwhite")
+       (link :rel "manifest" :href "/img/site.webmanifest")
+       (link :rel "stylesheet" :href (bust-cache "/style/dist.css"))
+       (link :rel "preconnect" :href "https://fonts.googleapis.com")
+       (link :rel "stylesheet" :href "https://fonts.googleapis.com/css2?family=Zen+Kurenaido&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-preload@2.0.0/preload.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))
+     (body
+       :hx-ext "head-support, response-targets, preload"
+       :hx-boost "true" :hx-target-404 "body" :hx-target-5* "body"
+       :class (<>
+                "h-[100svh] flex flex-col bg-[url(/img/bg.jpg)] bg-cover bg-center "
+                "p-2 md:p-8")
+       (div :class (<> 
+                     "bg-amber-50/90 flex flex-col flex-1 w-full max-w-[700px] overflow-hidden  shadow-sm "
+                     "px-2 pt-2 mx-auto md:px-8 md:pt-8")
+         (header :class "flex justify-between pb-2 md:pb-4 border-b-1"
+           (h1 :class "text-2xl md:text-4xl font-bold"
+             (a :href "/"
+               "skyizwhite"))
+           (nav :class "flex items-end"
+             (ul
+               :class "flex gap-4 text-lg [&_a]:underline [&_a]:hover:text-pink-500"
+               :preload t
+               (li (a :href "/bio" "bio"))
+               (li (a :href "/work" "work"))
+               (li (a :href "/blog" "blog")))))
+         (main :class "flex-1 pt-2 pb-4 md:pt-4 md:pb-8 overflow-y-scroll "
+           children))))))
diff --git a/static/img/avatar.jpg b/static/img/avatar.jpg
new file mode 100644
index 0000000..38cf5fc
Binary files /dev/null and b/static/img/avatar.jpg differ
diff --git a/static/img/bg.jpg b/static/img/bg.jpg
new file mode 100644
index 0000000..f1c176e
Binary files /dev/null and b/static/img/bg.jpg differ
diff --git a/static/img/me.webp b/static/img/me.webp
deleted file mode 100644
index 892723a..0000000
Binary files a/static/img/me.webp and /dev/null differ
diff --git a/static/style/global.css b/static/style/global.css
index 671406c..dc52305 100644
--- a/static/style/global.css
+++ b/static/style/global.css
@@ -1,11 +1,11 @@
 @import "tailwindcss";
 
 :root {
-  font-family: 'Noto Sans JP Variable', sans-serif;
+  font-family: "Zen Kurenaido", sans-serif;
 }
 
 @supports (font-variation-settings: normal) {
   :root {
-    font-family: 'Noto Sans JP Variable', sans-serif;
+    font-family: "Zen Kurenaido", sans-serif;
   }
 }