diff --git a/src/apps/officer-web/styles/prose.css b/src/apps/officer-web/styles/prose.css index 821b9a42..7410d8ca 100644 --- a/src/apps/officer-web/styles/prose.css +++ b/src/apps/officer-web/styles/prose.css @@ -169,8 +169,11 @@ .code-surface pre { margin: 0; padding: 0.75em 1em; - /* Room for the two copy buttons, so a long first line scrolls up to them rather than under them. */ + /* Room for the copy controls, which sit absolutely at the bottom-right of the block. Horizontal so a + long line scrolls past them rather than under them; vertical so the LAST line — the one they now + overlap — keeps its own space. */ padding-right: 5.5em; + padding-bottom: 2em; border-radius: 0.5rem; background: #0d1117; /* Scroll, never wrap: wrapping folds `ls -la`, `git log --oneline` and any other columnar output into @@ -186,6 +189,12 @@ padding-right: 10em; } +/* The positioning context for those controls. Without it they escape to the nearest positioned ancestor, + which is how a copy button ends up floating below the block it belongs to. */ +.code-surface { + position: relative; +} + .code-surface pre code { padding: 0; border-radius: 0; diff --git a/src/workspaces/officerdev/src/apps/Chat/components/CodeSurface.tsx b/src/workspaces/officerdev/src/apps/Chat/components/CodeSurface.tsx index 38d63ee2..718737b4 100644 --- a/src/workspaces/officerdev/src/apps/Chat/components/CodeSurface.tsx +++ b/src/workspaces/officerdev/src/apps/Chat/components/CodeSurface.tsx @@ -108,17 +108,18 @@ export const CodeSurface = ({ code, lang = '', startLine = 1, maxLines, numbered style={{ '--line-digits': digits, '--line-offset': startLine - 1 } as CSSProperties} > {code && ( - // Sticky, not absolute, and first in the flow so it has a flow position to stick to. A block - // taller than its scroll container — a live log tail, a 400-line read — used to carry its - // controls off the top edge, so the output you most want to copy was the one whose copy button - // you had to scroll back up to find. `h-0` keeps the row out of the vertical flow: it overlays - // the top of the block rather than pushing it down, which is what the old `absolute` did. + // Absolute, bottom-right, INSIDE the block — the controls belong to the code, so they sit on it + // rather than after it. `.code-surface` is `position: relative` for this (prose.css). + // + // Bottom rather than top: a copy button over the FIRST line covers the thing you are most likely + // to be reading, and on a one-line block — a single command, which is most of them here — it + // covers the whole thing. // // Always visible, not hover-revealed: a control you have to discover by waving the pointer at it // is a control most people never find, and on touch there is no hover to find it with at all. Two // buttons rather than one with a modifier — the destination decides which you want (a terminal, or // someone else's markdown), and a modifier nobody can see is a feature nobody uses. -