fix(maestro): flatten structured composer
The composer was a floating bordered card inset from the pane edge, and its send button was bottom-aligned beside the textarea, so it sank as the draft grew. It is now a flush band at the foot of the pane: one hairline rule against the transcript, which doubles as the focus indicator. The textarea spans the full width and the controls sit in a fixed strip below it, so the send button keeps its place however tall the draft grows. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
0dc10ffe76
commit
f78aa13b36
+11
-9
@@ -97,17 +97,19 @@ export function createStructuredConnection(
|
||||
autocomplete="off" aria-autocomplete="list" aria-expanded="false"
|
||||
aria-controls="structured-command-menu-${sessionId}"></textarea>
|
||||
</div>
|
||||
<div class="structured-config" hidden>
|
||||
<button type="button" class="structured-config-trigger" aria-haspopup="true"
|
||||
aria-expanded="false" aria-label="Session settings" title="Session settings">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h10M18 7h2M4 17h2M10 17h10M14 4v6M6 14v6"/></svg>
|
||||
<div class="structured-actions">
|
||||
<div class="structured-config" hidden>
|
||||
<button type="button" class="structured-config-trigger" aria-haspopup="true"
|
||||
aria-expanded="false" aria-label="Session settings" title="Session settings">
|
||||
<svg viewBox="0 0 24 24" aria-hidden="true"><path d="M4 7h10M18 7h2M4 17h2M10 17h10M14 4v6M6 14v6"/></svg>
|
||||
</button>
|
||||
<div class="structured-config-menu" role="group" aria-label="Session settings" hidden></div>
|
||||
</div>
|
||||
<button type="button" class="btn structured-cancel" hidden>Cancel turn</button>
|
||||
<button type="submit" class="btn btn-primary structured-send"><span>Send</span>
|
||||
<svg viewBox="0 0 20 20" aria-hidden="true"><path d="m7 5 5 5-5 5M12 10H3"/></svg>
|
||||
</button>
|
||||
<div class="structured-config-menu" role="group" aria-label="Session settings" hidden></div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary structured-send"><span>Send</span>
|
||||
<svg viewBox="0 0 20 20" aria-hidden="true"><path d="m7 5 5 5-5 5M12 10H3"/></svg>
|
||||
</button>
|
||||
<button type="button" class="btn structured-cancel" hidden>Cancel turn</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+53
-39
@@ -2176,12 +2176,14 @@ input.leaf-rename:focus {
|
||||
|
||||
.structured-config {
|
||||
position: relative;
|
||||
flex: 0 0 40px;
|
||||
flex: 0 0 32px;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
.structured-config-trigger {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -2219,7 +2221,7 @@ input.leaf-rename:focus {
|
||||
position: absolute;
|
||||
z-index: 20;
|
||||
bottom: calc(100% + var(--sp-2));
|
||||
right: 0;
|
||||
left: 0;
|
||||
width: min(320px, 86vw);
|
||||
padding: var(--sp-2);
|
||||
border: 1px solid var(--border-strong);
|
||||
@@ -3062,36 +3064,28 @@ input.leaf-rename:focus {
|
||||
}
|
||||
|
||||
/* The composer is a sibling of the scrolling transcript, not part of it: it
|
||||
stays reachable at the pane edge without changing transcript scroll math. */
|
||||
stays reachable at the pane edge without changing transcript scroll math.
|
||||
It is a flush band at the foot of the pane rather than a floating card —
|
||||
one hairline separates it from the transcript, and that hairline is also
|
||||
the focus indicator. Input and controls stack, so the send button keeps a
|
||||
fixed place at the composer's foot however tall the draft grows. */
|
||||
.structured-composer {
|
||||
flex: 0 0 auto;
|
||||
margin: var(--sp-2) var(--sp-3) max(var(--sp-2), env(safe-area-inset-bottom));
|
||||
padding: var(--sp-1);
|
||||
border: 1px solid var(--border-strong);
|
||||
border-radius: var(--r-3);
|
||||
background: var(--surface);
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
flex-direction: column;
|
||||
gap: var(--sp-1);
|
||||
box-shadow:
|
||||
inset 0 1px 0 color-mix(in oklab, var(--ink) 6%, transparent),
|
||||
var(--shadow-1);
|
||||
transition:
|
||||
border-color var(--dur-fast) var(--ease-out),
|
||||
box-shadow var(--dur-fast) var(--ease-out);
|
||||
padding: var(--sp-2) var(--sp-3) max(var(--sp-2), env(safe-area-inset-bottom));
|
||||
border-top: 1px solid var(--border);
|
||||
background: var(--bg);
|
||||
transition: border-color var(--dur-fast) var(--ease-out);
|
||||
}
|
||||
|
||||
.structured-composer:focus-within {
|
||||
border-color: var(--accent);
|
||||
box-shadow:
|
||||
inset 0 1px 0 color-mix(in oklab, var(--ink) 8%, transparent),
|
||||
0 0 0 3px var(--accent-tint),
|
||||
var(--shadow-1);
|
||||
border-top-color: var(--accent);
|
||||
}
|
||||
|
||||
.structured-input-wrap {
|
||||
position: relative;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
@@ -3100,24 +3094,40 @@ input.leaf-rename:focus {
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
max-height: 160px;
|
||||
min-height: 40px;
|
||||
min-height: 20px;
|
||||
resize: none;
|
||||
overflow-y: hidden;
|
||||
padding: 10px var(--sp-2);
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-radius: var(--r-2);
|
||||
background: transparent;
|
||||
color: var(--ink);
|
||||
font-size: var(--fs-13);
|
||||
line-height: 20px;
|
||||
}
|
||||
|
||||
.structured-input:focus-visible {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.structured-actions {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
gap: var(--sp-1);
|
||||
min-height: 32px;
|
||||
}
|
||||
|
||||
.structured-actions .structured-config {
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
.structured-composer .structured-send,
|
||||
.structured-composer .structured-cancel {
|
||||
height: 40px;
|
||||
min-height: 40px;
|
||||
height: 32px;
|
||||
min-height: 32px;
|
||||
border-radius: var(--r-2);
|
||||
font-family: var(--font-sans);
|
||||
font-size: var(--fs-12);
|
||||
}
|
||||
|
||||
.structured-composer .structured-send {
|
||||
@@ -3138,8 +3148,8 @@ input.leaf-rename:focus {
|
||||
}
|
||||
|
||||
.structured-composer .structured-send svg {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
fill: none;
|
||||
stroke: currentColor;
|
||||
stroke-width: 1.7;
|
||||
@@ -3169,17 +3179,21 @@ input.leaf-rename:focus {
|
||||
}
|
||||
|
||||
@media (max-width: 520px) {
|
||||
.structured-composer {
|
||||
margin: var(--sp-1) 0 0;
|
||||
padding-bottom: calc(var(--sp-1) + env(safe-area-inset-bottom, 0px));
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
border-left: 0;
|
||||
border-radius: var(--r-2) var(--r-2) 0 0;
|
||||
.structured-composer .structured-send,
|
||||
.structured-composer .structured-cancel {
|
||||
height: var(--tap);
|
||||
min-height: var(--tap);
|
||||
font-size: var(--fs-13);
|
||||
}
|
||||
|
||||
.structured-config-menu {
|
||||
right: calc(-1 * (var(--control-h) + var(--sp-2)));
|
||||
.structured-actions {
|
||||
min-height: var(--tap);
|
||||
}
|
||||
|
||||
.structured-config,
|
||||
.structured-config-trigger {
|
||||
width: var(--tap);
|
||||
height: var(--tap);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user