feat(chat): center chat reading column and full-height context sidebar

Replaces the full-variant flex layout with a single CSS grid owning the
messages column, input bar, and context sidebar. Messages and input bar
share a centered ~820px reading track (--chat-reading-width token) so
the mic button can't get pushed off-screen on wide monitors, and the
context sidebar spans grid-row 1/-1 so it runs the full height from the
chat header down to the bottom edge instead of stopping above the input
bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-15 07:11:08 -04:00
parent 36fb71699b
commit ad4fe3d783
2 changed files with 33 additions and 14 deletions
+2
View File
@@ -54,6 +54,8 @@
--page-max-width: 1200px;
--page-padding-x: 1rem;
--sidebar-width: 260px;
--chat-reading-width: min(820px, 100%);
--chat-context-sidebar-width: 220px;
--color-accent-warm: #b8860b;
--color-accent-warm-light: #d4a017;
--color-primary-solid: #7c3aed;
+31 -14
View File
@@ -312,7 +312,7 @@ defineExpose({ focus, prefill, send })
<template>
<!-- FULL VARIANT -->
<template v-if="variant === 'full'">
<div class="chat-body" :class="{ 'chat-body--has-sidebar': hasContextSidebar }">
<div class="chat-full" :class="{ 'chat-full--has-sidebar': hasContextSidebar }">
<!-- Message list -->
<div ref="messagesEl" class="messages-container">
<div class="messages-inner">
@@ -391,10 +391,9 @@ defineExpose({ focus, prefill, send })
</div>
</template>
</aside>
</div>
<!-- Input area (hidden when readOnly) -->
<div v-if="!readOnly" class="input-wrapper">
<!-- Input area (hidden when readOnly) -->
<div v-if="!readOnly" class="input-wrapper">
<!-- Scope chip -->
<div v-if="showScopeChip" class="scope-chip-row">
<div class="scope-chip-wrapper">
@@ -476,6 +475,7 @@ defineExpose({ focus, prefill, send })
@submit="onSubmit"
@abort="store.cancelGeneration()"
/>
</div>
</div>
</template>
@@ -528,18 +528,34 @@ defineExpose({ focus, prefill, send })
</template>
<style scoped>
/* ── Full variant layout ── */
.chat-body {
/* ── Full variant layout ──
* Single grid owns the reading column + context sidebar + input bar so
* messages and input bar share one centered reading track while the
* context sidebar spans the full height from header to bottom of view.
* The sidebar column collapses to 0 when there are no context notes.
*/
.chat-full {
--chat-sidebar-col: 0px;
flex: 1;
display: flex;
min-height: 0;
display: grid;
grid-template-columns:
1fr
minmax(0, var(--chat-reading-width))
1fr
var(--chat-sidebar-col);
grid-template-rows: minmax(0, 1fr) auto;
overflow: hidden;
}
.chat-full--has-sidebar {
--chat-sidebar-col: var(--chat-context-sidebar-width);
}
.messages-container {
flex: 1;
grid-column: 2;
grid-row: 1;
overflow-y: auto;
padding: 1rem;
padding: 1rem 1rem 0;
mask-image: linear-gradient(to bottom, transparent, black 20px, black calc(100% - 20px), transparent);
-webkit-mask-image: linear-gradient(to bottom, transparent, black 20px, black calc(100% - 20px), transparent);
}
@@ -558,11 +574,10 @@ defineExpose({ focus, prefill, send })
opacity: 0.35;
}
/* Context sidebar */
/* Context sidebar — spans full height (rows 1 and 2) of the chat grid */
.context-sidebar {
width: 200px;
min-width: 160px;
max-width: 220px;
grid-column: 4;
grid-row: 1 / -1;
border-left: 1px solid var(--color-border);
padding: 0.75rem 0.5rem;
overflow-y: auto;
@@ -616,8 +631,10 @@ defineExpose({ focus, prefill, send })
.context-note-remove:hover { color: #ef4444; }
.context-note-add:hover { color: var(--color-primary); }
/* Input wrapper */
/* Input wrapper — lives in the same reading column as messages */
.input-wrapper {
grid-column: 2;
grid-row: 2;
border-top: 1px solid var(--color-border);
padding: 0.5rem 1rem 0.75rem;
display: flex;