Fix flash dismiss button and make it a compact toast
Use $el.closest().remove() instead of Alpine reactive state for the
close button — simpler and avoids x-transition.opacity attribute issues
in Phlex. Restyle as a centered, inline pill with a border and rounded
corners instead of a full-width bar.

https://claude.ai/code/session_01NLGBcJgbiyWGDBGFh8DRas
change
commit 55c1932f207f87eeaace02d6bb9f0bb37047609b
author Claude <noreply@anthropic.com>
date
parent 6cdcc28b
diff --git a/lib/ketchup/views/dashboard.rb b/lib/ketchup/views/dashboard.rb
index 3cf5006..edd98ff 100644
--- a/lib/ketchup/views/dashboard.rb
+++ b/lib/ketchup/views/dashboard.rb
@@ -42,19 +42,21 @@ module Views
 
       undo_path = @flash["undo_path"]
 
-      div(class: "flash-bar", "x-data": "{ show: true }", "x-show": "show", "x-transition.opacity": true) do
-        span(class: "flash-message") { @flash["message"] }
-        if undo_path
+      div(class: "flash-wrap") do
+        div(class: "flash-bar", "x-data": true) do
+          span(class: "flash-message") { @flash["message"] }
+          if undo_path
+            button(
+              class: "flash-undo-btn",
+              "x-on:click": "fetch('#{undo_path}', {method: 'DELETE'}).then(() => location.reload())"
+            ) { "Undo" }
+          end
           button(
-            class: "flash-undo-btn",
-            "x-on:click": "fetch('#{undo_path}', {method: 'DELETE'}).then(() => location.reload())"
-          ) { "Undo" }
+            class: "flash-close-btn",
+            "x-on:click": "$el.closest('.flash-wrap').remove()",
+            **{ "aria-label": "Dismiss" }
+          ) { "\u00d7" }
         end
-        button(
-          class: "flash-close-btn",
-          "x-on:click": "show = false",
-          **{ "aria-label": "Dismiss" }
-        ) { "\u00d7" }
       end
     end
 
diff --git a/public/css/app.css b/public/css/app.css
index edaf30a..8198ca6 100644
--- a/public/css/app.css
+++ b/public/css/app.css
@@ -106,16 +106,22 @@ h2 { font-size: var(--step-0); font-weight: 600; }
 /* Flash bar */
 /* -------------------- */
 
-.flash-bar {
+.flash-wrap {
   display: flex;
-  align-items: center;
   justify-content: center;
+  padding: var(--space-xs) var(--space-l);
+}
+
+.flash-bar {
+  display: inline-flex;
+  align-items: center;
   gap: var(--space-xs);
-  padding: var(--space-2xs) var(--space-l);
+  padding: var(--space-2xs) var(--space-s);
   font-size: var(--step--1);
   color: #666;
-  background: #f8f8f8;
-  border-block-end: 1px solid #eee;
+  background: #f5f5f5;
+  border: 1px solid #e0e0e0;
+  border-radius: 4px;
 }
 
 .flash-undo-btn {
@@ -134,7 +140,6 @@ h2 { font-size: var(--step-0); font-weight: 600; }
   cursor: pointer;
   font-size: var(--step-0);
   line-height: 1;
-  margin-inline-start: var(--space-2xs);
 }
 
 .flash-close-btn:hover {