Files
replypier/frontend/src/webclient/widget-surface.css
T

243 lines
8.7 KiB
CSS
Raw Normal View History

/**
* SHARED chat-surface theme — the single place the widget's themed appearance is
* defined. Imported by BOTH the real widget (`WidgetBuilder.vue`) and the admin
* preview (`AgentChatPreviewPanel.vue`) so they can never drift.
*
* Every rule is scoped under `.chat-container.rp-surface` (both surfaces add the
* `rp-surface` marker class to their panel root). The extra class both contains the
* global import to the widget and gives these rules enough specificity to win over
* each component's own scoped `[data-v-*]` CSS. Every value comes from the `--rp-*`
* custom properties emitted by `themeCssVars()` in `widget-theme.ts` — no hard-coded
* per-theme values live here.
*
* Components keep only their own NON-themed, structural CSS (layout, animations,
* socket/streaming bits, admin-mock chrome) in their scoped <style> blocks.
*/
/* ===== Panel ===== */
.chat-container.rp-surface {
font-family: var(--rp-body-font);
color: var(--rp-text);
}
.chat-container.rp-surface .chat-panel {
background: var(--rp-card);
color: var(--rp-text);
}
/* ===== Header ===== */
.chat-container.rp-surface .chat-header {
padding: 14px 16px;
border-bottom: 1px solid var(--rp-hairline);
background: transparent;
}
.chat-container.rp-surface .header-info h3 {
color: var(--rp-text);
font-family: var(--rp-body-font);
font-size: 14.5px;
font-weight: 600;
line-height: 1.15;
}
/* --rp-presence is the accent when it is readable on the card, otherwise the
contrast-derived muted colour (see themeCssVars). */
.chat-container.rp-surface .rp-presence,
.chat-container.rp-surface .status-text {
color: var(--rp-presence, var(--rp-accent));
font-size: 11.5px;
}
.chat-container.rp-surface .status-indicator.online {
background: var(--rp-presence, var(--rp-accent));
box-shadow: none;
}
/* ===== Avatars — circle by default, rounded-square on mono (Terminal); no ring ===== */
.chat-container.rp-surface .header-orb,
.chat-container.rp-surface .header-avatar {
width: 34px;
height: 34px;
border-radius: var(--rp-avatar-radius);
border: none;
box-shadow: none;
object-fit: cover;
flex-shrink: 0;
}
.chat-container.rp-surface .rp-msg-avatar,
.chat-container.rp-surface .rp-msg-avatar-orb,
.chat-container.rp-surface .rp-msg-avatar-img,
.chat-container.rp-surface .rp-welcome-orb,
.chat-container.rp-surface .rp-welcome-avatar {
width: 28px;
height: 28px;
border-radius: var(--rp-avatar-radius);
border: none;
box-shadow: none;
flex-shrink: 0;
display: block;
}
.chat-container.rp-surface .rp-msg-avatar-img,
.chat-container.rp-surface .rp-welcome-avatar { object-fit: cover; }
/* ===== Messages ===== */
.chat-container.rp-surface .message {
max-width: 100%;
gap: 9px;
align-items: flex-start;
}
.chat-container.rp-surface .message-bubble {
padding: 10px 14px;
font-size: 14px;
line-height: 1.5;
box-shadow: none;
max-width: 84%;
}
/* Collapse markdown paragraph margins so a one-line reply is a compact bubble. */
.chat-container.rp-surface .message-bubble p { margin: 0; }
.chat-container.rp-surface .message-bubble p + p { margin-top: 0.5em; }
/* Markdown links inside messages: clearly a link and clickable (v-html content, so
this must be a global rule — scoped styles don't reach it). Inherits the bubble
colour so it's readable on both the agent surface and the accent user bubble. */
.chat-container.rp-surface .message-bubble a {
color: inherit;
text-decoration: underline;
text-underline-offset: 2px;
font-weight: 600;
cursor: pointer;
}
.chat-container.rp-surface .message-bubble a:hover { opacity: 0.82; }
/* Markdown code & wide content (v-html, so global rules): scroll inside the
bubble instead of painting past it and forcing the chat to scroll sideways.
Backgrounds derive from currentColor so they read on light and dark bubbles. */
.chat-container.rp-surface .message-bubble pre {
max-width: 100%;
overflow-x: auto;
margin: 0.5em 0;
padding: var(--space-sm, 12px);
border-radius: 8px;
background: color-mix(in srgb, currentColor 8%, transparent);
-webkit-overflow-scrolling: touch;
scrollbar-width: thin;
}
.chat-container.rp-surface .message-bubble pre code {
/* Code keeps its formatting; the <pre> scrollbar handles long lines. */
white-space: pre;
overflow-wrap: normal;
background: none;
padding: 0;
}
.chat-container.rp-surface .message-bubble code {
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
font-size: 0.9em;
background: color-mix(in srgb, currentColor 8%, transparent);
padding: 1px 5px;
border-radius: 6px;
}
.chat-container.rp-surface .message-bubble table {
display: block;
max-width: 100%;
overflow-x: auto;
border-collapse: collapse;
margin: 0.5em 0;
}
.chat-container.rp-surface .message-bubble th,
.chat-container.rp-surface .message-bubble td {
border: 1px solid color-mix(in srgb, currentColor 20%, transparent);
padding: 4px 8px;
}
/* Agent/bot bubble: agent surface + hairline, tail top-left. */
.chat-container.rp-surface .agent-message .message-bubble,
.chat-container.rp-surface .assistant-message .message-bubble {
background: var(--rp-agent-bg);
color: var(--rp-text);
border: 1px solid var(--rp-hairline);
border-radius: var(--rp-bubble-tail) var(--rp-bubble) var(--rp-bubble) var(--rp-bubble);
}
/* User bubble: accent fill, contrast text, tail bottom-right. */
.chat-container.rp-surface .user-message .message-bubble {
background: var(--rp-accent);
color: var(--rp-on-accent);
border: none;
border-radius: var(--rp-bubble) var(--rp-bubble) var(--rp-bubble-tail) var(--rp-bubble);
}
/* ===== Quick-action pills ===== */
.chat-container.rp-surface .rp-quick-action {
padding: 8px 14px;
border-radius: 999px;
border: 1px solid color-mix(in srgb, var(--rp-accent) 66%, transparent);
background: color-mix(in srgb, var(--rp-accent) 18%, transparent);
color: var(--rp-text);
font-family: var(--rp-body-font);
font-size: 12.5px;
font-weight: 600;
cursor: pointer;
transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.chat-container.rp-surface .rp-quick-action:hover:not(:disabled) {
background: var(--rp-accent);
color: var(--rp-on-accent);
border-color: var(--rp-accent);
}
.chat-container.rp-surface.theme-terminal .rp-quick-action { border-radius: 6px; }
/* ===== Input bar + send (transparent bar — card shows through, no grey band) ===== */
.chat-container.rp-surface .chat-input {
background: transparent;
border-top: 1px solid var(--rp-hairline);
}
.chat-container.rp-surface .message-input input,
.chat-container.rp-surface .email-input input {
border-radius: var(--rp-field-radius);
border: 1px solid color-mix(in srgb, var(--rp-accent) 30%, var(--rp-hairline));
background: color-mix(in srgb, var(--rp-text) 6%, transparent);
color: var(--rp-text);
font-family: var(--rp-body-font);
font-size: 14px;
}
.chat-container.rp-surface .message-input input::placeholder,
.chat-container.rp-surface .email-input input::placeholder {
color: var(--rp-muted);
opacity: 1;
}
.chat-container.rp-surface .message-input input:focus,
.chat-container.rp-surface .email-input input:focus {
border-color: var(--rp-accent);
box-shadow: 0 0 0 3px color-mix(in srgb, var(--rp-accent) 22%, transparent);
}
.chat-container.rp-surface .send-button {
width: 42px;
min-width: 42px;
height: 42px;
flex-shrink: 0;
border: none;
border-radius: var(--rp-field-radius);
background: var(--rp-accent);
color: var(--rp-on-accent);
cursor: pointer;
}
/* ===== Powered-by footer (transparent — card shows, no grey band) ===== */
.chat-container.rp-surface .powered-by,
.chat-container.rp-surface .powered-by-welcome {
background: transparent;
border-top: none;
color: var(--rp-muted);
font-family: var(--rp-body-font);
}
.chat-container.rp-surface .rp-powered-prefix { color: var(--rp-muted); opacity: 1; }
.chat-container.rp-surface .rp-brand { color: var(--rp-text); font-weight: 700; }
/* Mono (Terminal): monospace across the whole surface. */
.chat-container.rp-surface.theme-terminal,
.chat-container.rp-surface.theme-terminal .chat-panel,
.chat-container.rp-surface.theme-terminal .header-info h3,
.chat-container.rp-surface.theme-terminal .message-bubble,
.chat-container.rp-surface.theme-terminal .rp-quick-action,
.chat-container.rp-surface.theme-terminal .message-input input,
.chat-container.rp-surface.theme-terminal .powered-by {
font-family: var(--rp-body-font);
}
/* Glass: frosted panel. */
.chat-container.rp-surface.theme-glass .chat-panel {
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
}