fabrica

hanna/fabrica

style(web): shorten close/reopen buttons; trim labels list top padding

906fb7b · hanna committed on 2026-07-25

Close/Reopen buttons drop the noun ("Close" instead of "Close pull request").
Zero the first label row's top padding so the list doesn't double up on the
card padding.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed by hannaSSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
3 files changed · +12 −9UnifiedSplit
assets/base.css +3 −0
@@ -371,6 +371,9 @@ body.drawer-open .drawer-backdrop {
371.label-list .entry-row {371.label-list .entry-row {
372 padding: 0.85rem 0;372 padding: 0.85rem 0;
373}373}
374.label-list .entry-row:first-child {
375 padding-top: 0;
376}
374.label-list .entry-row-body {377.label-list .entry-row-body {
375 display: flex;378 display: flex;
376 flex-direction: row;379 flex-direction: row;
crates/web/src/issues.rs +6 −6
@@ -268,7 +268,7 @@ pub(crate) async fn view(
268 }268 }
269 @if issue.locked() { (locked_note(can_write)) }269 @if issue.locked() { (locked_note(can_write)) }
270 @if can_write || (is_author && !issue.locked()) {270 @if can_write || (is_author && !issue.locked()) {
271 (comment_box(&issue, &csrf, kind, can_write))271 (comment_box(&issue, &csrf, can_write))
272 }272 }
273 }273 }
274 aside class="issue-side" {274 aside class="issue-side" {
@@ -366,10 +366,10 @@ pub(crate) fn state_badge(st: IssueState, is_pull: bool) -> Markup {
366}366}
367367
368/// The close/reopen button (posts to the state endpoint).368/// The close/reopen button (posts to the state endpoint).
369pub(crate) fn state_button(issue: &Issue, csrf: &str, kind: Kind) -> Markup {369pub(crate) fn state_button(issue: &Issue, csrf: &str) -> Markup {
370 let (target, label) = match issue.state {370 let (target, label) = match issue.state {
371 IssueState::Open => ("closed", format!("Close {}", kind.noun)),371 IssueState::Open => ("closed", "Close"),
372 IssueState::Closed => ("open", format!("Reopen {}", kind.noun)),372 IssueState::Closed => ("open", "Reopen"),
373 };373 };
374 html! {374 html! {
375 form method="post" action=(format!("/issue/{}/state", issue.id)) class="inline-form" {375 form method="post" action=(format!("/issue/{}/state", issue.id)) class="inline-form" {
@@ -392,7 +392,7 @@ pub(crate) fn locked_note(can_write: bool) -> Markup {
392392
393/// The comment box: a textarea plus the state/lock/comment actions. The Comment393/// The comment box: a textarea plus the state/lock/comment actions. The Comment
394/// button references the form via `form=` so no forms are nested.394/// button references the form via `form=` so no forms are nested.
395pub(crate) fn comment_box(issue: &Issue, csrf: &str, kind: Kind, can_write: bool) -> Markup {395pub(crate) fn comment_box(issue: &Issue, csrf: &str, can_write: bool) -> Markup {
396 let comment_form = format!("comment-{}", issue.id);396 let comment_form = format!("comment-{}", issue.id);
397 html! {397 html! {
398 div class="card comment-form" {398 div class="card comment-form" {
@@ -401,7 +401,7 @@ pub(crate) fn comment_box(issue: &Issue, csrf: &str, kind: Kind, can_write: bool
401 textarea name="body" rows="4" placeholder="Leave a comment (markdown)" required {}401 textarea name="body" rows="4" placeholder="Leave a comment (markdown)" required {}
402 }402 }
403 div class="comment-actions" {403 div class="comment-actions" {
404 (state_button(issue, csrf, kind))404 (state_button(issue, csrf))
405 @if can_write { (lock_button(issue, csrf)) }405 @if can_write { (lock_button(issue, csrf)) }
406 button class="btn btn-primary inline-btn" type="submit" form=(comment_form) { "Comment" }406 button class="btn btn-primary inline-btn" type="submit" form=(comment_form) { "Comment" }
407 }407 }
crates/web/src/pulls.rs +3 −3
@@ -25,8 +25,8 @@ use crate::AppState;
25use crate::diff;25use crate::diff;
26use crate::error::{AppError, AppResult};26use crate::error::{AppError, AppResult};
27use crate::issues::{27use crate::issues::{
28 Kind, access_for, assignee_form, comment_box, comment_card, deps_section, edit_issue_form,28 access_for, assignee_form, comment_box, comment_card, deps_section, edit_issue_form, issue_url,
29 issue_url, label_form, locked_note, repo_of_issue, respond_redirect, state_badge, username,29 label_form, locked_note, repo_of_issue, respond_redirect, state_badge, username,
30};30};
31use crate::layout::page;31use crate::layout::page;
32use crate::pages::build_chrome;32use crate::pages::build_chrome;
@@ -167,7 +167,7 @@ pub(crate) async fn view(
167 (merge_panel(&issue, &pr, mergeable, blocked, &csrf))167 (merge_panel(&issue, &pr, mergeable, blocked, &csrf))
168 @if issue.locked() { (locked_note(can_write)) }168 @if issue.locked() { (locked_note(can_write)) }
169 @if can_write || (is_author && !issue.locked()) {169 @if can_write || (is_author && !issue.locked()) {
170 (comment_box(&issue, &csrf, Kind::pulls(), can_write))170 (comment_box(&issue, &csrf, can_write))
171 }171 }
172 }172 }
173 aside class="issue-side" {173 aside class="issue-side" {