Empty-state section cards: action button collides with hint text — harden CSS and extract SectionCard #275
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab#275
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Bug
At empty states, the action button in a section card's head row can sit on top of the hint text below it. Reported on repo settings → Imports: the "+ Add import" button covers the hint "Other lab repos this repo's instances may read as read-only snapshots, mounted at spawn." Reporter sees it persistently, on desktop and mobile, on a fresh build of main. Other sections built on the same pattern (e.g. Secrets) are presumed affected.
Diagnosis (from code inspection)
The overlap class is enabled by a fragile stack — no absolute positioning is involved:
.hint-block(web/src/styles/forms.css) uses a negative top margin (margin: -0.35rem 0 0.9rem), pulling the hint up toward whatever precedes it. It hard-codes an assumption about the height of the element above..card-head(web/src/styles/cards.css) does not reset theh2margins, unlike the sibling pattern.section-head(web/src/styles/shell.css, which hash2 { margin: 0 }). The head row's height therefore depends on browser-default heading margins — font-metric/zoom dependent, and the headings loadSource Serif 4withfont-display: swap, so the height even shifts during font load. When the row renders short, the button (36px,button.small) is the tallest item and the hint's negative margin pulls the text into it.<p class="empty">repeated at ~16 call sites.Note: the exact pixel mechanism was not reproduced in-session (no browser available); the fix below removes the entire enabling class rather than patching one geometry. The reporter verifies visually before merge.
Fix (agreed with reporter)
1. CSS hardening (fixes every page immediately):
.hint-block: drop the negative top margin (margin: 0 0 0.9rem)..card-head: addh2 { margin: 0; overflow-wrap: anywhere; }to match.section-head h2. Since the heading's default margins previously provided the row's vertical breathing room, give.card-headan explicitmargin-bottom(align with.section-head'smargin-bottom: var(--space-3)) so the visual rhythm is preserved deliberately instead of accidentally.2. Extract a shared
SectionCardcomponent (web/src/components/SectionCard.tsx):title,actionslot (JSX for the head-row button),hint(optional), and body children (error banner / add-form / empty-vs-list markup stay with the caller).<p class="empty">inside children for now.3. Migrate all settings sections to
SectionCard:web/src/routes/repo-settings/sections/: Imports, Secrets, Schedules, Agents, Autoland, Branches, Danger, General, Integrations, Runner.web/src/routes/settings/sections/where the pattern appears (e.g. Notifications).Acceptance criteria
SectionCard; component test asserts the structure (title, action slot, hint, children render in order).npm run build,npm run test,npm run lintclean.Follow-up umbrella for the rest of the frontend (per-family component extraction, inventory-first): #276.