main
/* Conversation surfaces favour reading rhythm and clear, quiet affordances. */
.chat-room {
background: var(--shell-surface);
}
.chat-room.chat-panel-resizing,
.chat-room.chat-panel-resizing * {
cursor: col-resize !important;
user-select: none;
}
.chat-main {
position: relative;
min-width: 0;
container-type: inline-size;
}
.chat-header {
display: flex;
min-height: 76px;
align-items: center;
gap: 12px;
/* 13px(而不是 14px):标题块 48 + 上下留白 26 + 底部 1px 线恰好 75,由
min-height 收到 76,与右侧面板头的 76 精确对齐。 */
padding: 13px 24px;
border-bottom: 1px solid var(--shell-hairline);
background: color-mix(in srgb, var(--shell-surface) 94%, var(--shell-field));
}
/* 纯字形:无底色无边框,`#` 用主墨色(浅色主题下渲染为黑色)。38px 的占位
保持与两行标题的垂直对齐。 */
.chat-channel-icon {
display: grid;
width: 38px;
height: 38px;
flex: 0 0 auto;
place-items: center;
border-radius: 12px;
color: var(--shell-ink);
background: transparent;
}
.chat-heading {
min-width: 0;
flex: 1;
}
.chat-topic {
margin-top: 2px;
overflow: hidden;
color: var(--shell-ink-muted);
font-size: 12px;
line-height: 1.5;
text-overflow: ellipsis;
white-space: nowrap;
}
.chat-header-actions {
display: flex;
flex: 0 0 auto;
align-items: center;
gap: 4px;
}
.chat-header-actions > button,
.chat-panel-close {
display: inline-grid;
width: 36px;
height: 36px;
place-items: center;
border-radius: 10px;
color: var(--shell-ink-muted);
transition:
color 160ms,
background 160ms;
}
.chat-header-actions > button:hover,
.chat-panel-close:hover {
color: var(--shell-ink);
background: var(--shell-active);
}
.chat-action-label {
display: none;
}
.chat-message-list {
padding: 8px 12px 16px;
scroll-padding-block: 20px;
}
.chat-history-start {
margin: 20px 8px 8px;
color: var(--shell-ink-muted);
font-size: 12px;
text-align: center;
}
.chat-day-divider {
margin-top: 10px;
color: var(--shell-ink-muted);
font-size: 11px;
font-weight: 600;
letter-spacing: 0.03em;
}
.chat-message-row {
margin: 1px 0;
border-radius: 10px;
}
.chat-message-row:hover {
background: color-mix(in srgb, var(--shell-field) 72%, transparent);
}
.chat-message-row.chat-message-grouped {
min-height: 24px;
}
.chat-message-body {
max-width: 820px;
line-height: 1.65;
overflow-wrap: anywhere;
}
.chat-message-toolbar {
position: absolute;
z-index: 20; /* above the jump-to-latest pill, so its popover is never buried */
right: 10px;
top: -15px;
display: flex;
align-items: center;
gap: 2px;
padding: 3px;
border: 1px solid var(--shell-hairline);
border-radius: 10px;
background: var(--shell-surface);
box-shadow: var(--shell-shadow);
opacity: 0;
pointer-events: none; /* hidden, but it still covered the row above and ate its clicks */
/*
* Fade only. A `transform` here would make the toolbar the containing block
* for the reaction picker and the more-menu, which are `position: fixed`
* children placed with viewport coordinates — they would fly off-screen and
* the buttons would look dead.
*/
transition: opacity 150ms;
}
.chat-message-row:hover .chat-message-toolbar,
.chat-message-toolbar:focus-within,
.chat-message-toolbar:has([aria-pressed="true"]) {
opacity: 1;
pointer-events: auto;
}
/* Square icon buttons are the toolbar's own actions, never the popovers it hosts. */
.chat-message-toolbar > button,
.chat-message-toolbar > div > button {
display: grid;
width: 30px;
height: 30px;
place-items: center;
border-radius: 7px;
color: var(--shell-ink-muted);
}
.chat-message-toolbar > button:hover,
.chat-message-toolbar > div > button:hover {
color: var(--shell-ink);
background: var(--shell-field);
}
.chat-unread-marker {
margin: 8px 0;
}
.chat-transcript-notice {
min-height: 280px;
}
.chat-notice-icon {
display: grid;
width: 48px;
height: 48px;
place-items: center;
border: 1px solid var(--shell-hairline);
border-radius: 16px;
color: var(--shell-ink-muted);
background: var(--shell-field);
}
.chat-notice-title {
font-size: 18px;
font-weight: 600;
}
.chat-notice-description {
max-width: 360px;
color: var(--shell-ink-muted);
font-size: 14px;
line-height: 1.7;
}
.chat-composer-band {
flex: 0 0 auto;
padding: 12px 20px 18px;
border-top: 1px solid var(--shell-hairline);
background: var(--shell-surface);
}
.chat-composer {
overflow: hidden;
border: 1px solid var(--shell-hairline);
border-radius: 14px;
background: var(--shell-field);
box-shadow: 0 2px 8px rgb(24 28 31 / 3%);
}
.chat-composer:focus-within {
border-color: var(--shell-tile);
}
.chat-composer-input {
display: flex;
min-height: 46px;
padding: 5px 12px 0;
}
.chat-composer-toolbar {
display: flex;
align-items: center;
gap: 4px;
min-height: 42px;
padding: 4px 8px 8px;
}
.chat-composer-tool {
display: grid;
width: 34px;
height: 34px;
place-items: center;
border-radius: 9px;
color: var(--shell-ink-muted);
transition:
background 160ms,
color 160ms;
}
.chat-composer-tool:hover {
color: var(--shell-ink);
background: var(--shell-active);
}
.chat-composer-help {
display: flex;
gap: 12px;
margin-left: 6px;
color: var(--shell-ink-muted);
font-size: 11px;
}
.chat-composer-help kbd {
padding: 1px 4px;
border: 1px solid var(--shell-hairline);
border-radius: 4px;
background: var(--shell-surface);
font-family: inherit;
}
.chat-send-button {
display: inline-flex;
min-width: 70px;
height: 34px;
align-items: center;
justify-content: center;
gap: 6px;
margin-left: auto;
padding: 0 11px;
border-radius: 9px;
color: white;
background: var(--shell-action);
font-size: 12px;
font-weight: 600;
transition:
filter 160ms,
transform 160ms;
}
.chat-send-button:hover:not(:disabled) {
filter: brightness(1.08);
}
.chat-send-button:active:not(:disabled) {
transform: scale(0.97);
}
.chat-send-button:disabled {
cursor: not-allowed;
opacity: 0.45;
}
.chat-side-panel {
position: relative;
width: min(var(--chat-panel-width, 380px), calc(100% - 100px));
max-width: calc(100% - 100px);
box-shadow: -10px 0 24px rgb(24 28 31 / 3%);
}
.chat-panel-resize-handle {
position: absolute;
z-index: 30;
top: 0;
bottom: 0;
left: -6px;
width: 12px;
cursor: col-resize;
touch-action: none;
outline: none;
}
.chat-panel-resize-handle::after {
position: absolute;
top: 50%;
left: 5px;
width: 2px;
height: 44px;
border-radius: 999px;
background: var(--shell-focus);
content: "";
opacity: 0;
transform: translateY(-50%);
transition: opacity 150ms;
}
.chat-panel-resize-handle:hover::after,
.chat-panel-resize-handle:focus-visible::after,
.chat-panel-resizing .chat-panel-resize-handle::after {
opacity: 1;
}
.chat-panel-focus-scrim {
position: absolute;
z-index: 25;
inset: 0;
background: color-mix(in srgb, var(--shell-surface) 38%, transparent);
backdrop-filter: blur(8px) saturate(0.86);
-webkit-backdrop-filter: blur(8px) saturate(0.86);
}
.chat-panel-header {
min-height: 76px;
padding: 0 16px;
}
.chat-panel-empty {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
padding: 40px 24px;
text-align: center;
}
.chat-panel-empty-icon {
display: grid;
width: 44px;
height: 44px;
place-items: center;
border-radius: 15px;
color: var(--shell-ink-muted);
background: var(--shell-field);
}
.chat-popover {
box-shadow: 0 14px 40px rgb(24 28 31 / 16%);
}
.chat-popover button {
cursor: pointer;
}
/* The picker ships its own palette; re-point its variables at the shell tokens
* so search, category tabs and hover states read as part of the same surface. */
.chat-emoji-picker .EmojiPickerReact {
--epr-bg-color: var(--shell-surface);
--epr-picker-border-color: var(--shell-hairline);
--epr-picker-border-radius: 10px;
--epr-text-color: var(--shell-ink-muted);
--epr-search-input-bg-color: var(--shell-field);
--epr-search-input-bg-color-active: var(--shell-field);
--epr-search-border-color: var(--shell-hairline);
--epr-search-border-color-active: var(--shell-focus);
--epr-hover-bg-color: var(--shell-active);
--epr-focus-bg-color: var(--shell-active);
--epr-category-label-bg-color: color-mix(in srgb, var(--shell-surface) 90%, transparent);
--epr-category-icon-active-color: var(--shell-action);
--epr-category-icon-inactive-color: var(--shell-ink-muted);
}
/* The dark theme re-points every variable at an --epr-dark-* twin, so the
* tokens have to be overridden there instead. */
.chat-emoji-picker .epr-dark-theme {
--epr-dark-bg-color: var(--shell-surface);
--epr-dark-picker-border-color: var(--shell-hairline);
--epr-dark-text-color: var(--shell-ink-muted);
--epr-dark-search-input-bg-color: var(--shell-field);
--epr-dark-search-input-bg-color-active: var(--shell-field);
--epr-dark-hover-bg-color: var(--shell-active);
--epr-dark-focus-bg-color: var(--shell-active);
--epr-dark-category-label-bg-color: color-mix(in srgb, var(--shell-surface) 90%, transparent);
--epr-dark-category-icon-active-color: var(--shell-ink);
--epr-dark-category-icon-inactive-color: var(--shell-ink-muted);
}
.chat-emoji-picker .epr-main * {
font-family: inherit;
}
/* The picker scrolls its own body, so the popover must not clip it. */
.chat-popover:has(.chat-emoji-picker) {
padding: 4px;
}
/* A reader can intentionally leave the chat column very narrow while widening
* a detail pane. Keep the header compact and horizontal at every width rather
* than allowing its title and topic to wrap into an unusable column. */
@container (max-width: 480px) {
.chat-main > .chat-header {
min-height: 60px;
padding: 10px 12px;
gap: 8px;
}
.chat-main .chat-topic {
display: none;
}
.chat-main .chat-header-actions {
gap: 0;
}
.chat-main .chat-header-actions > button {
width: 32px;
height: 32px;
}
.chat-main .chat-header-actions > button:nth-child(n + 4) {
display: none;
}
}
@container (max-width: 300px) {
.chat-main .chat-heading {
display: none;
}
.chat-main .chat-header-actions > button:nth-child(n + 3) {
display: none;
}
}
@container (max-width: 180px) {
.chat-main .chat-header-actions {
display: none;
}
}
.chat-panel-scrim {
display: none;
}
@media (max-width: 1200px) {
.chat-panel-scrim {
display: block;
position: fixed;
inset: 0;
z-index: 24;
background: rgb(18 20 22 / 40%);
}
.chat-side-panel {
position: fixed;
z-index: 25;
right: 0;
top: 0;
bottom: 0;
width: min(380px, 88vw);
max-width: none;
box-shadow: -18px 0 48px rgb(24 28 31 / 18%);
}
.chat-panel-resize-handle,
.chat-panel-focus-scrim {
display: none;
}
}
@media (max-width: 760px) {
.chat-header {
min-height: 68px;
padding: 12px 16px;
}
.chat-panel-header {
min-height: 68px;
}
.chat-channel-icon {
width: 34px;
height: 34px;
border-radius: 10px;
}
.chat-header-actions {
gap: 1px;
}
.chat-header-actions > button {
width: 32px;
height: 32px;
}
.chat-message-list {
padding: 6px 8px 12px;
}
.chat-message-row {
gap: 10px;
padding-left: 8px;
padding-right: 8px;
}
.chat-message-toolbar {
right: 8px;
opacity: 1;
pointer-events: auto;
}
.chat-message-toolbar > :nth-child(n + 4) {
display: none;
}
.chat-composer-band {
padding: 10px 12px 12px;
}
.chat-composer-help {
display: none;
}
.chat-side-panel {
width: 100%;
}
}
@media (max-width: 420px) {
.chat-header {
gap: 8px;
padding: 10px 12px;
}
.chat-header-actions > button {
width: 30px;
height: 30px;
}
}
@media (prefers-reduced-motion: reduce) {
.chat-message-toolbar,
.chat-send-button {
transition: none;
}
}