contact card: edit and new as one button group
Gloss' button group draws them together with a divider on a wide
screen; on a phone they stack, a pad apart, the line break standing in
for the divider.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0186Ru2zvdWEwdwGhQ5V9z5X
change
commit e46f29afcb52439b64b9680fe5310636adac3603
author Claude <noreply@anthropic.com>
date
parent 5f0c9c04
diff --git a/lib/pro_tacts/admin/contact_card.rb b/lib/pro_tacts/admin/contact_card.rb
index 870bb6b..63c4a2b 100644
--- a/lib/pro_tacts/admin/contact_card.rb
+++ b/lib/pro_tacts/admin/contact_card.rb
@@ -161,11 +161,24 @@ module ProTacts
               @groups.each { render GroupTag.new(group: it) }
             end
           end
-          button(type: "button", data_size: "sm", popovertarget: GroupDialog::ID) { "edit" } if @dialog
-          button(type: "submit", form: NEW, data_size: "sm") { "new" } if @new
+          if @new
+            # Gloss' button group, whose divider tells the two apart
+            # where they sit side by side (admin.css stacks them on a
+            # phone).
+            div(role: "group", aria_label: "Groups") do
+              edit_button
+              button(type: "submit", form: NEW, data_size: "sm") { "new" }
+            end
+          elsif @dialog
+            edit_button
+          end
         end
       end
 
+      #: () -> void
+      def edit_button
+        button(type: "button", data_size: "sm", popovertarget: GroupDialog::ID) { "edit" }
+      end
 
       # The type in one column and the value in the other, with the
       # group that lends the row named under the value when one does.
diff --git a/public/admin.css b/public/admin.css
index 28c2fd2..a7047a9 100644
--- a/public/admin.css
+++ b/public/admin.css
@@ -1119,44 +1119,39 @@ span.avatar[data-size="lg"] {
    Baseline-aligned: a grid item blockifies, so the tag's inline-flex
    becomes a flex container, which takes its baseline from its first
    item — the tag's text — and so shares the value's. A contact
-   card's "edit" button takes the same place, a flex container like
-   the tag, and its "new" the column after it — or, on a phone, the
-   row under it, where side by side the two would take the tags'
-   column down to a word and push a long tag under the buttons. */
+   card's "edit" and "new" take the same place as Gloss' button group,
+   a flex container like the tag. */
 .detail-grid dd:has(> .tag),
-.detail-grid dd:has(> button) {
+.detail-grid dd:has(> button),
+.detail-grid dd:has(> [role="group"]) {
   display: grid;
   grid-template-columns: minmax(0, 1fr) auto;
   align-items: baseline;
   column-gap: var(--gl-space-s);
 }
 .detail-grid dd > .tag,
-.detail-grid dd > button {
+.detail-grid dd > button,
+.detail-grid dd > [role="group"] {
   grid-column: 2;
   grid-row: 1;
 }
 .detail-grid dd:has(> .tag) > div,
-.detail-grid dd:has(> button) > div {
+.detail-grid dd:has(> button) > div,
+.detail-grid dd:has(> [role="group"]) > div:not([role="group"]) {
   grid-column: 1;
 }
-.detail-grid dd:has(> button + button) {
-  grid-template-columns: minmax(0, 1fr) auto auto;
-}
-.detail-grid dd > button + button {
-  grid-column: 3;
-}
+/* On a phone the group stacks, the line break standing in for the
+   divider: side by side the two take the tags' column down to a word. */
 @media (max-width: 48rem) {
-  .detail-grid dd:has(> button + button) {
-    grid-template-columns: minmax(0, 1fr) auto;
-    grid-template-rows: auto 1fr;
-  }
-  .detail-grid dd:has(> button + button) > div {
-    grid-row: span 2;
+  .detail-grid dd > [role="group"] {
+    flex-direction: column;
+    align-items: flex-end;
   }
-  .detail-grid dd > button + button {
-    grid-column: 2;
-    grid-row: 2;
-    justify-self: end;
+  /* The two pads between the labels drawn together to one, so the
+     pair reads as one control rather than two rows of the grid. */
+  .detail-grid dd > [role="group"] > button + button {
+    border-inline-start: none;
+    margin-block-start: calc(-1 * var(--gl-space-3xs));
   }
 }
 /* A nameless group shown by its id (Admin::GroupLabel): set in mono,