Shared prompt blocks (Images panel, viewer details, Library cards and
saved texts, recorded runs) now render the approved mock's markup
(app.js promptBlock a298-302, concept.css s550-588), #249 D22:
- section.prompt-section.<role>[aria-label="<Role> prompt"] >
.prompt-heading (span.role-label "+ Positive prompt" / "- Negative
prompt"; .prompt-actions: copy button.icon-btn "Copy <role> prompt",
then send button.send.icon-btn "Send <role> prompt to ComfyUI") +
p.prompt-text.
- No per-block source line; a file's evidence moves to the panel badge
(D2) and "File & provenance" (D3). Recorded runs keep every field's
source in "Frozen field provenance".
- Empty text reads "No negative prompt (explicitly empty)" and still
sends an explicit clear. Absent, ambiguous and unresolved roles render
p.prompt-text.muted with the existing status strings and no actions;
unknown role names render nothing and cannot be sent or copied.
- Copy shows the shared toast "Prompt copied."; without a clipboard it
opens the concept's "Copy prompt" select-to-copy dialog.
- The data-send-role / data-copy-role contract is unchanged.
The D22 interim overrides (26px actions, prompt-text margins, copy
status, source line) are retired so the concept's rules apply; the
action buttons measure the mock's 31x31. pre.prompt-text styling stays
only for the Library editor's Archive dialog and frozen field
provenance, which keep their own markup until their page rebuilds.
Test selector mapping:
.prompt-block / .prompt-positive -> .prompt-section(.positive)
.prompt-block-heading h3 -> .prompt-heading span.role-label
region pre / pre.prompt-text -> p.prompt-text
"Empty negative prompt" -> "No negative prompt (explicitly empty)"
"Send <role> prompt" -> "Send <role> prompt to ComfyUI"
.prompt-source / copy status line -> removed (toast or Copy prompt dialog)
copy button 30x26 -> 31x31 (measured in the mock)