diff --git a/lib/core.ex b/lib/core.ex
index 3071bda..3ce5c5e 100644
--- a/lib/core.ex
+++ b/lib/core.ex
@@ -1,4 +1,4 @@
 defmodule Core do
   @moduledoc false
-  use Boundary, deps: [Schema], exports: [Accounts, Posts, Author]
+  use Boundary, deps: [Schema], exports: [Accounts, Posts, Author, DateTime]
 end
diff --git a/lib/core/date_time.ex b/lib/core/date_time.ex
new file mode 100644
index 0000000..6ee4ef1
--- /dev/null
+++ b/lib/core/date_time.ex
@@ -0,0 +1,9 @@
+defmodule Core.DateTime do
+  @local_time_zone "America/New_York"
+
+  def to_local_time(nil), do: nil
+
+  def to_local_time(date_time) do
+    DateTime.shift_zone!(date_time, @local_time_zone)
+  end
+end
diff --git a/lib/core/posts.ex b/lib/core/posts.ex
index 832fd0a..cd5e84a 100644
--- a/lib/core/posts.ex
+++ b/lib/core/posts.ex
@@ -50,11 +50,15 @@ defmodule Core.Posts do
     |> Flop.validate_and_run(params, for: Schema.Post)
   end
 
-  def publish_date(%Schema.Post{published_at: nil}), do: nil
+  def publish_date_time(%Schema.Post{published_at: nil}), do: nil
 
-  def publish_date(%Schema.Post{published_at: published_at}) do
-    published_at
-    |> DateTime.shift_zone!("America/New_York")
+  def publish_date_time(%Schema.Post{published_at: published_at}) do
+    Core.DateTime.to_local_time(published_at)
+  end
+
+  def publish_date(%Schema.Post{} = post) do
+    post
+    |> publish_date_time()
     |> DateTime.to_date()
   end
 
diff --git a/lib/core/posts/post.ex b/lib/core/posts/post.ex
index 38b51bd..45cb7e1 100644
--- a/lib/core/posts/post.ex
+++ b/lib/core/posts/post.ex
@@ -6,7 +6,7 @@ defmodule Core.Posts.Post do
   def content_changeset(%Schema.Post{} = post, attrs) do
     changeset =
       post
-      |> cast(attrs, [:tid, :kind, :slug, :title, :body])
+      |> cast(attrs, [:tid, :kind, :slug, :title, :body, :deleted_at, :published_at])
       |> validate_required([:kind], message: "must have a kind")
       |> validate_required([:body], message: "must have a body")
 
@@ -40,7 +40,9 @@ defmodule Core.Posts.Post do
     changeset = change(post)
 
     if is_nil(get_field(changeset, :published_at)) do
-      put_change(changeset, :published_at, published_at)
+      changeset
+      |> put_change(:deleted_at, nil)
+      |> put_change(:published_at, published_at)
     else
       changeset
     end
@@ -50,7 +52,9 @@ defmodule Core.Posts.Post do
     changeset = change(post)
 
     if is_nil(get_field(changeset, :deleted_at)) do
-      put_change(changeset, :deleted_at, deleted_at)
+      changeset
+      |> put_change(:published_at, nil)
+      |> put_change(:deleted_at, deleted_at)
     else
       changeset
     end
@@ -81,7 +85,12 @@ defmodule Core.Posts.Post do
     end
 
     def default_order(query \\ base()) do
-      order_by(query, [posts: p], desc: :inserted_at, desc: :updated_at)
+      order_by(query, [posts: p],
+        desc: :published_at,
+        desc: :inserted_at,
+        desc: :updated_at,
+        desc: :id
+      )
     end
 
     def where_kind(query \\ base(), kind) do
diff --git a/lib/schema/post.ex b/lib/schema/post.ex
index 033c38c..94ed07f 100644
--- a/lib/schema/post.ex
+++ b/lib/schema/post.ex
@@ -5,11 +5,11 @@ defmodule Schema.Post do
   @derive {
     Flop.Schema,
     filterable: [],
-    sortable: [:published_at, :id],
+    sortable: [:published_at, :inserted_at, :updated_at, :id],
     pagination_types: [:first, :last],
     default_order: %{
-      order_by: [:published_at, :id],
-      order_directions: [:desc, :desc]
+      order_by: [:published_at, :inserted_at, :updated_at, :id],
+      order_directions: [:desc, :desc, :desc, :desc]
     },
     default_pagination_type: :first,
     default_limit: 20,
diff --git a/lib/web/components/core_components.ex b/lib/web/components/core_components.ex
index 8d1b43a..5c2d348 100644
--- a/lib/web/components/core_components.ex
+++ b/lib/web/components/core_components.ex
@@ -10,7 +10,8 @@ defmodule Web.CoreComponents do
   attr :name, :any
   attr :label, :string, default: nil
   attr :value, :any
-  attr :type, :string, default: "text", values: ~w[text password textarea]
+  attr :class, :string, default: nil
+  attr :type, :string, default: "text", values: ~w[text password textarea datetime-local]
   attr :field, FormField
   attr :errors, :list, default: []
   attr :rest, :global, include: ~w[disabled form pattern placeholder readonly required]
@@ -36,9 +37,9 @@ defmodule Web.CoreComponents do
 
   def input(%{type: "textarea"} = assigns) do
     ~H"""
-    <div>
+    <div class={["flex flex-col", @class]}>
       <.label for={@id}>{@label}</.label>
-      <textarea id={@id} name={@name}>{Phoenix.HTML.Form.normalize_value(@type, @value)}</textarea>
+      <textarea id={@id} name={@name} class="h-80">{Phoenix.HTML.Form.normalize_value(@type, @value)}</textarea>
       <.error :for={error <- @errors}>{error}</.error>
     </div>
     """
@@ -46,7 +47,7 @@ defmodule Web.CoreComponents do
 
   def input(assigns) do
     ~H"""
-    <div>
+    <div class="flex flex-col">
       <.label for={@id}>{@label}</.label>
       <input
         id={@id}
diff --git a/lib/web/controllers/blog_html/index.html.heex b/lib/web/controllers/blog_html/index.html.heex
index 75e183b..feca9d7 100644
--- a/lib/web/controllers/blog_html/index.html.heex
+++ b/lib/web/controllers/blog_html/index.html.heex
@@ -16,7 +16,7 @@
                   >
                     <h3 class="p-name u-url">{blog.title}</h3>
                     <div class="text-gray-500 dt-published">
-                      <.timex value={blog.published_at} format="{Mfull} {D}" />
+                      <.timex value={Core.Posts.publish_date_time(blog)} format="{Mfull} {D}" />
                     </div>
                   </.link>
                 </article>
diff --git a/lib/web/controllers/blog_html/show.html.heex b/lib/web/controllers/blog_html/show.html.heex
index 3955b33..2ef6229 100644
--- a/lib/web/controllers/blog_html/show.html.heex
+++ b/lib/web/controllers/blog_html/show.html.heex
@@ -3,10 +3,18 @@
     <header class="mb-4">
       <h1 class="p-name text-2xl font-bold mb-2">{@blog.title}</h1>
       <%= if @blog.published_at do %>
-        <div class="text-sm text-gray-500 flex items-center">
+        <div class="text-sm text-gray-500 flex items-center gap-x-2">
           <span class="p-author h-card">{Core.Author.get(:name)}</span>
-          <span class="mx-2">·</span>
-          <.timex value={@blog.published_at} format="{Mfull} {D}, {YYYY}" class="dt-published" />
+          <span>·</span>
+          <.timex
+            value={Core.Posts.publish_date_time(@blog)}
+            format="{Mfull} {D}, {YYYY}"
+            class="dt-published"
+          />
+          <%= if @current_user do %>
+            <span>·</span>
+            <.link navigate={~p"/admin/posts/#{@blog}"}>edit</.link>
+          <% end %>
         </div>
       <% end %>
     </header>
diff --git a/lib/web/controllers/page_html/home.html.heex b/lib/web/controllers/page_html/home.html.heex
index 76dd544..abf61e3 100644
--- a/lib/web/controllers/page_html/home.html.heex
+++ b/lib/web/controllers/page_html/home.html.heex
@@ -18,7 +18,7 @@
             >
               <h3 class="p-name u-url">{blog.title}</h3>
               <div class="text-gray-500 dt-published">
-                <.timex value={blog.published_at} format="{Mfull} {D}" />
+                <.timex value={Core.Posts.publish_date_time(blog)} format="{Mfull} {D}" />
               </div>
             </.link>
           </article>
diff --git a/lib/web/controllers/status_html.ex b/lib/web/controllers/status_html.ex
index 627cc8f..fb49a00 100644
--- a/lib/web/controllers/status_html.ex
+++ b/lib/web/controllers/status_html.ex
@@ -49,7 +49,7 @@ defmodule Web.StatusHTML do
               <span class="mx-2 text-sm text-gray-500">·</span>
               <div class="text-sm text-gray-500">
                 <.timex
-                  value={@status.published_at}
+                  value={Core.Posts.publish_date_time(@status)}
                   format="{relative}"
                   formatter={:relative}
                   class="dt-published"
diff --git a/lib/web/controllers/status_html/show.html.heex b/lib/web/controllers/status_html/show.html.heex
index 093462c..bcd4982 100644
--- a/lib/web/controllers/status_html/show.html.heex
+++ b/lib/web/controllers/status_html/show.html.heex
@@ -10,7 +10,7 @@
   </div>
 
   <article class="h-entry p-4 border border-gray-200">
-    <header class="flex items-center mb-3">
+    <header class="flex mb-3 justify-between">
       <div class="h-card flex items-center gap-3 p-author">
         <%= if Core.Author.get(:avatar_url) do %>
           <img
@@ -34,6 +34,10 @@
           </p>
         </div>
       </div>
+
+      <%= if @current_user do %>
+        <.link class="text-sm text-gray-500" navigate={~p"/admin/posts/#{@status}"}>edit</.link>
+      <% end %>
     </header>
 
     <div class="e-content my-4">
@@ -43,7 +47,7 @@
     <footer class="mt-4 border-t border-gray-200 pt-2 text-sm text-gray-500">
       <%= if @status.published_at do %>
         <.timex
-          value={@status.published_at}
+          value={Core.Posts.publish_date_time(@status)}
           format="{Mfull} {D}, {YYYY} at {h12}:{m} {AM}"
           class="dt-published"
         />
diff --git a/lib/web/live/admin_post_live.ex b/lib/web/live/admin_post_live.ex
index 7970e80..54d0366 100644
--- a/lib/web/live/admin_post_live.ex
+++ b/lib/web/live/admin_post_live.ex
@@ -53,7 +53,13 @@ defmodule Web.AdminPostLive do
     socket =
       case Core.Posts.create_or_update_post(post, attrs) do
         {:ok, post} ->
+          form =
+            post
+            |> Core.Posts.change_post(%{})
+            |> to_form()
+
           socket
+          |> assign(post: post, form: form)
           |> put_flash(:info, "post saved")
           |> push_patch(to: ~p"/admin/posts/#{post}", replace: true)
 
@@ -68,7 +74,12 @@ defmodule Web.AdminPostLive do
     socket =
       case Core.Posts.publish_post(post) do
         {:ok, post} ->
-          assign(socket, post: post)
+          form =
+            post
+            |> Core.Posts.change_post(%{})
+            |> to_form()
+
+          assign(socket, post: post, form: form)
 
         _ ->
           socket
@@ -81,7 +92,12 @@ defmodule Web.AdminPostLive do
     socket =
       case Core.Posts.unpublish_post(post) do
         {:ok, post} ->
-          assign(socket, post: post)
+          form =
+            post
+            |> Core.Posts.change_post(%{})
+            |> to_form()
+
+          assign(socket, post: post, form: form)
 
         _ ->
           socket
@@ -94,7 +110,12 @@ defmodule Web.AdminPostLive do
     socket =
       case Core.Posts.delete_post(post) do
         {:ok, post} ->
-          assign(socket, post: post)
+          form =
+            post
+            |> Core.Posts.change_post(%{})
+            |> to_form()
+
+          assign(socket, post: post, form: form)
 
         _ ->
           socket
@@ -107,7 +128,12 @@ defmodule Web.AdminPostLive do
     socket =
       case Core.Posts.undelete_post(post) do
         {:ok, post} ->
-          assign(socket, post: post)
+          form =
+            post
+            |> Core.Posts.change_post(%{})
+            |> to_form()
+
+          assign(socket, post: post, form: form)
 
         _ ->
           socket
diff --git a/lib/web/live/admin_post_live.html.heex b/lib/web/live/admin_post_live.html.heex
index 0fcf196..b8144bc 100644
--- a/lib/web/live/admin_post_live.html.heex
+++ b/lib/web/live/admin_post_live.html.heex
@@ -1,33 +1,41 @@
-<main>
-  <header>
-    <h1>{page_title(@post, @live_action)}</h1>
-  </header>
-
-  <.form for={@form} phx-change="validate" phx-submit="save">
-    <.input :if={@post.kind == :blog} type="text" field={@form[:title]} />
+<.form
+  for={@form}
+  phx-change="validate"
+  phx-submit="save"
+  class="flex flex-col md:flex-row p-4 gap-4"
+>
+  <div class="flex-grow flex flex-col gap-y-4">
+    <.input :if={@post.kind == :blog} type="text" label="title" field={@form[:title]} />
+    <.input type="textarea" field={@form[:body]} label="body" class="md:flex-grow" />
+  </div>
+  <div class="md:w-80 flex flex-col gap-y-2">
+    <.button type="submit" class="self-end">save</.button>
+    <.link
+      :if={@post.published_at}
+      class="self-end"
+      navigate={Web.Paths.public_post_path(@post)}
+      target="_blank"
+    >
+      view
+    </.link>
+    <.input type="datetime-local" label="published (utc)" field={@form[:published_at]} />
+    <%= if @post.published_at do %>
+      <.button phx-click="unpublish" class="self-end">unpublish</.button>
+    <% else %>
+      <.button phx-click="publish" class="self-end">publish</.button>
+    <% end %>
+    <.input type="datetime-local" label="deleted (utc)" field={@form[:deleted_at]} />
+    <%= if @post.deleted_at do %>
+      <.button phx-click="undelete" class="self-end">undelete</.button>
+    <% else %>
+      <.button phx-click="delete" class="self-end">delete</.button>
+    <% end %>
     <.input
       :if={@post.kind == :blog}
+      label="slug"
       type="text"
       field={@form[:slug]}
       disabled={not update_slug?(@post)}
     />
-    <.input type="textarea" field={@form[:body]} />
-
-    <.button type="submit">save</.button>
-  </.form>
-
-  <%= if @live_action == :edit do %>
-    <div>
-      <%= if @post.published_at do %>
-        <.button phx-click="unpublish">unpublish</.button>
-      <% else %>
-        <.button phx-click="publish">publish</.button>
-      <% end %>
-      <%= if @post.deleted_at do %>
-        <.button phx-click="undelete">undelete</.button>
-      <% else %>
-        <.button phx-click="delete">delete</.button>
-      <% end %>
-    </div>
-  <% end %>
-</main>
+  </div>
+</.form>