返回 DeepSeek-Reasonix
TerminalBlock.css
根目录 / desktop / frontend / src / components / harness-chat / TerminalBlock.css
1 /* Ported from DeepSeek Harness c291e7961a (MIT). */
2 .dsh-TerminalBlock-block {
3 --dsl-terminal-radius: 12px;
4 --dsl-terminal-line-height: 22px;
5 /* Rebindable by consumers (CodeBlock's --dsl-code-block-content-font
6 pattern): a surface wanting the smaller code size rebinds this together
7 with --dsl-terminal-line-height on its own container. */
8 --dsl-terminal-font: var(--dsw-font-markdown-code-block);
9 /* The card's own left inset, holding the run-state dot in a column of its own
10 so it never competes with the commands for horizontal space. */
11 --dsl-terminal-gutter: 30px;
12
13 position: relative;
14 margin: 16px 0;
15 /* The gutter is the card's OWN padding, not a margin: every consumer rewrites
16 `margin` wholesale (each render site sets its own indent), which silently
17 cancelled the reservation and let the dot fall outside the card into a
18 container that clips it. Owning the reservation here keeps the invariant
19 with the component that depends on it. */
20 padding-left: var(--dsl-terminal-gutter);
21 color: var(--dsw-alias-label-primary);
22 background: var(--dsw-alias-markdown-code-block);
23 border-radius: var(--dsl-terminal-radius);
24 /* Clip the banner to the card's own radius: when a consumer adds a border,
25 the banner's equal corner radius no longer nests inside it and leaves a
26 notch at the corner. Nothing inside renders out of the box. */
27 overflow: hidden;
28 }
29
30 /* The status pill and copy control top-align to the FIRST prompt row (their
31 heights are capped to the prompt line, so on a multi-line command they sit
32 with the first command instead of floating mid-banner). */
33 .dsh-TerminalBlock-header {
34 display: flex;
35 align-items: flex-start;
36 gap: 12px;
37 /* Pulled back across the card's gutter padding so the banner spans the FULL
38 surface, then re-inset by the same amount so the prompt text and the dot
39 keep their positions. The banner shares the card's own surface (no banner
40 token): the l2 divider below is the section boundary. */
41 margin-left: calc(-1 * var(--dsl-terminal-gutter));
42 padding: 9px 14px 9px var(--dsl-terminal-gutter);
43 border-top-left-radius: var(--dsl-terminal-radius);
44 border-top-right-radius: var(--dsl-terminal-radius);
45 /* A long multi-line command scrolls inside the banner (same cap as the
46 IN/OUT card's sections) instead of pushing the output off screen. */
47 max-height: 150px;
48 overflow-y: auto;
49 }
50
51 /* Banner scrollbar floats off the card edge like the output's. */
52 .dsh-TerminalBlock-header::-webkit-scrollbar-thumb {
53 border: 2px solid transparent;
54 background-clip: padding-box;
55 border-radius: 6px;
56 }
57
58 .dsh-TerminalBlock-header::-webkit-scrollbar-track {
59 margin: 6px;
60 }
61
62 /* Full-width l2 hairline between the command banner and the body — the same
63 divider the IN/OUT card draws between its sections. A running card is
64 banner-only, so it draws none. */
65 .dsh-TerminalBlock-block:not([data-running]) .dsh-TerminalBlock-header {
66 border-bottom: 0.5px solid var(--dsw-alias-border-l2);
67 }
68
69 /* One row per command line. The prompt column is the only element allowed to
70 shrink; the status pill and the copy control keep their intrinsic width. */
71 .dsh-TerminalBlock-prompt {
72 display: flex;
73 flex-direction: column;
74 min-width: 0;
75 flex: 1;
76 font: var(--dsl-terminal-font);
77 }
78
79 .dsh-TerminalBlock-promptLine {
80 position: relative;
81 display: flex;
82 align-items: baseline;
83 gap: 8px;
84 min-width: 0;
85 line-height: var(--dsl-terminal-line-height);
86 }
87
88 /* Out of flow inside the card's own gutter padding, so the reservation and the
89 dot move together and no consumer margin can pull them apart; the dot neither
90 indents its command nor depends on the command's text metrics to line up.
91 Centered against the row's line box, not the code font's baseline. */
92 .dsh-TerminalBlock-runState {
93 position: absolute;
94 left: calc(-1 * var(--dsl-terminal-gutter) + 8px);
95 top: 50%;
96 transform: translateY(-50%);
97 }
98
99 /* The dot is aria-hidden; this is its text label for assistive technology. */
100 .dsh-TerminalBlock-runStateLabel {
101 position: absolute;
102 width: 1px;
103 height: 1px;
104 overflow: hidden;
105 clip-path: inset(50%);
106 white-space: nowrap;
107 }
108
109 .dsh-TerminalBlock-cwd {
110 flex: none;
111 color: var(--dsw-alias-label-tertiary);
112 }
113
114 /* `pre`, not `nowrap`: the prompt row renders the command verbatim, and
115 `nowrap` collapses the repeated spaces, tabs, and alignment of an indented
116 continuation. Both hold the single row and the ellipsis. */
117 .dsh-TerminalBlock-command {
118 min-width: 0;
119 color: var(--dsw-alias-label-primary);
120 overflow: hidden;
121 text-overflow: ellipsis;
122 white-space: pre;
123 }
124
125 /* Capped to the prompt's line height (Pill's own 24px height would exceed a
126 smaller-font prompt row and stretch the banner). Sticky against the
127 banner's own scroll so the pill and the copy control stay in reach while a
128 long command scrolls underneath. */
129 .dsh-TerminalBlock-status {
130 flex: none;
131 position: sticky;
132 top: 0;
133 height: var(--dsl-terminal-line-height);
134 color: var(--dsw-alias-state-error-primary);
135 }
136
137 .dsh-TerminalBlock-copyButton {
138 flex: none;
139 position: sticky;
140 top: 0;
141 /* Card surface, not transparent: the control is sticky over the banner's
142 own scroll, so scrolled command text must not bleed through it. */
143 background-color: var(--dsw-alias-markdown-code-block);
144 border: none;
145 padding: 0;
146 margin: 0;
147 color: var(--dsw-alias-label-secondary);
148 cursor: pointer;
149 font: var(--dsw-font-xs-13);
150 line-height: var(--dsl-terminal-line-height);
151 }
152
153 /* Vertical scrolling lives on the OUTPUT, not the card root: a root scroller
154 would run its scrollbar over the banner (and the copy control), while here
155 the banner stays pinned and the bar sits inside the output's right padding.
156 Unset, the max-height is none and the auto overflow never engages. */
157 .dsh-TerminalBlock-output {
158 max-height: var(--dsl-terminal-output-max-height, none);
159 padding: 12px 14px 12px 0;
160 font: var(--dsl-terminal-font);
161 overflow-x: auto;
162 overflow-y: auto;
163 }
164
165 /* Both output scrollbars (vertical cap, horizontal pre overflow) float 2px
166 off the card edge: a transparent border clips the thumb inward so it never
167 hugs the rounded corner. */
168 .dsh-TerminalBlock-output::-webkit-scrollbar-thumb {
169 border: 2px solid transparent;
170 background-clip: padding-box;
171 border-radius: 6px;
172 }
173
174 /* Track end-margins keep the thumb's travel out of the card's rounded
175 corners in both directions. */
176 .dsh-TerminalBlock-output::-webkit-scrollbar-track {
177 margin: 6px;
178 }
179
180 /* No wrapping, no word-break: alignment is the payload of terminal output. */
181 .dsh-TerminalBlock-line {
182 min-height: var(--dsl-terminal-line-height);
183 white-space: pre;
184 }
185
186 .dsh-TerminalBlock-expand {
187 display: block;
188 width: 100%;
189 padding: 0;
190 border: none;
191 background-color: transparent;
192 color: var(--dsw-alias-label-tertiary);
193 cursor: pointer;
194 font: inherit;
195 text-align: left;
196 }
197
198 .dsh-TerminalBlock-expand:hover {
199 color: var(--dsw-alias-label-secondary);
200 }
201
202 .dsh-TerminalBlock-empty {
203 padding: 12px 14px 12px 0;
204 font: var(--dsl-terminal-font);
205 color: var(--dsw-alias-label-tertiary);
206 }
207
207 lines CSS