Files
open-design/apps/web/src/index.css
marco 5dd70b5016
Some checks failed
ci / Validate workspace (push) Successful in 12m32s
landing-page-ci / Validate landing page (push) Successful in 9m41s
landing-page-deploy / Deploy landing page (push) Failing after 5m23s
github-metrics / Generate repository metrics SVG (push) Failing after 2m6s
refresh-contributors-wall / Refresh contributors wall cache bust (push) Failing after 12s
Initial import: open-design source for helix-mind.ai distribution
This repository contains the open-design daemon CLI source code, built
and packaged at https://helix-mind.ai/cli/open-design/latest.tgz for use
by the HelixMind /design slash command.

Licenses: Apache-2.0 (root) + MIT (skills/*)
2026-05-06 20:50:24 +02:00

11051 lines
267 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@import url('https://fonts.googleapis.com/css2?family=Cairo:wght@400;500;600;700&display=swap');
/* ============================================================
Open Design — visual language modeled on claude.ai/design
============================================================ */
:root {
/* Surface palette — warmer paper, hairline borders, soft shadows.
The entry view and project view share the same warm cream backdrop
(--bg) so transitioning between them feels seamless. --bg-app is kept
as an alias for compatibility but now resolves to the same value. */
--bg: #faf9f7;
--bg-app: #faf9f7;
--bg-panel: #ffffff;
--bg-subtle: #f4f2ed;
--bg-muted: #ece9e2;
--bg-elevated: #ffffff;
--border: #ebe8e1;
--border-strong: #d8d4cb;
--border-soft: #f1eee7;
--text: #1a1916;
--text-strong: #0d0c0a;
--text-muted: #74716b;
--text-soft: #989590;
--text-faint: #b3b0a8;
/* Accent — Claude rust/burnt-sienna. */
--accent: #c96442;
--accent-strong: #b45a3b;
--accent-soft: #f5d8cb;
--accent-tint: #fbeee5;
--accent-hover: #b45a3b;
/* Semantic accent tints used by tool / status pills. */
--green: #1f7a3a;
--green-bg: #e8f7ee;
--green-border: #c6ead2;
--blue: #2348b8;
--blue-bg: #e8efff;
--blue-border: #c8d6ff;
--purple: #6c3aa6;
--purple-bg: #f3ecf9;
--purple-border: #e4d4f1;
--red: #9c2a25;
--red-bg: #fdecea;
--red-border: #f5c6c2;
--amber: #b26200;
--amber-bg: #fff3e0;
--shadow-xs: 0 1px 0 rgba(28, 27, 26, 0.04);
--shadow-sm: 0 1px 2px rgba(28, 27, 26, 0.05), 0 1px 3px rgba(28, 27, 26, 0.04);
--shadow-md: 0 6px 24px rgba(28, 27, 26, 0.07), 0 2px 6px rgba(28, 27, 26, 0.04);
--shadow-lg: 0 24px 60px rgba(28, 27, 26, 0.16), 0 8px 16px rgba(28, 27, 26, 0.07);
--radius-sm: 6px;
--radius: 10px;
--radius-lg: 14px;
--radius-pill: 999px;
--serif: 'Source Serif Pro', 'Source Serif 4', 'Iowan Old Style', 'Apple Garamond', Georgia, 'Times New Roman', serif;
--sans: -apple-system, BlinkMacSystemFont, 'Inter', 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
--mono: ui-monospace, 'SF Mono', SFMono-Regular, Menlo, Consolas, monospace;
}
/* Dark theme variables — shared between explicit [data-theme="dark"] and the
OS-level prefers-color-scheme media query (system mode = no data-theme attr). */
[data-theme="dark"] {
color-scheme: dark;
--bg: #1a1917;
--bg-app: #1a1917;
--bg-panel: #222120;
--bg-subtle: #272523;
--bg-muted: #2e2c29;
--bg-elevated: #2a2825;
--border: #333128;
--border-strong: #46433c;
--border-soft: #2a2825;
--text: #e8e4dc;
--text-strong: #f2ede4;
--text-muted: #9a9690;
--text-soft: #6e6b65;
--text-faint: #4e4b46;
--accent: #d97a56;
--accent-strong: #e8896a;
--accent-soft: #3d2318;
--accent-tint: #2e1a12;
--accent-hover: #e8896a;
--green: #4caf72;
--green-bg: #0f2a18;
--green-border: #1a4028;
--blue: #6b8fe8;
--blue-bg: #0f1a38;
--blue-border: #1a2c58;
--purple: #a87dd4;
--purple-bg: #1e1030;
--purple-border: #321a50;
--red: #e06b65;
--red-bg: #2a0e0c;
--red-border: #451714;
--amber: #e09a40;
--amber-bg: #2a1a04;
--shadow-xs: 0 1px 0 rgba(0, 0, 0, 0.2);
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.2);
--shadow-md: 0 6px 24px rgba(0, 0, 0, 0.4), 0 2px 6px rgba(0, 0, 0, 0.25);
--shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.6), 0 8px 16px rgba(0, 0, 0, 0.3);
}
/* System mode: follow OS preference when no explicit data-theme is set. */
@media (prefers-color-scheme: dark) {
html:not([data-theme]) {
color-scheme: dark;
--bg: #1a1917;
--bg-app: #1a1917;
--bg-panel: #222120;
--bg-subtle: #272523;
--bg-muted: #2e2c29;
--bg-elevated: #2a2825;
--border: #333128;
--border-strong: #46433c;
--border-soft: #2a2825;
--text: #e8e4dc;
--text-strong: #f2ede4;
--text-muted: #9a9690;
--text-soft: #6e6b65;
--text-faint: #4e4b46;
--accent: #d97a56;
--accent-strong: #e8896a;
--accent-soft: #3d2318;
--accent-tint: #2e1a12;
--accent-hover: #e8896a;
--green: #4caf72;
--green-bg: #0f2a18;
--green-border: #1a4028;
--blue: #6b8fe8;
--blue-bg: #0f1a38;
--blue-border: #1a2c58;
--purple: #a87dd4;
--purple-bg: #1e1030;
--purple-border: #321a50;
--red: #e06b65;
--red-bg: #2a0e0c;
--red-border: #451714;
--amber: #e09a40;
--amber-bg: #2a1a04;
--shadow-xs: 0 1px 0 rgba(0, 0, 0, 0.2);
--shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.2);
--shadow-md: 0 6px 24px rgba(0, 0, 0, 0.4), 0 2px 6px rgba(0, 0, 0, 0.25);
--shadow-lg: 0 24px 60px rgba(0, 0, 0, 0.6), 0 8px 16px rgba(0, 0, 0, 0.3);
}
}
* { box-sizing: border-box; }
html, body, #root { height: 100%; margin: 0; }
body {
font-family: var(--sans);
color: var(--text);
background: var(--bg-app);
font-size: 13.5px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.od-loading-shell {
min-height: 100vh;
display: grid;
place-items: center;
color: var(--text-muted);
background: var(--bg-app);
font: 500 13px/1.4 var(--sans);
}
/* -------- Buttons --------------------------------------------------- */
button {
font: inherit;
color: var(--text);
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 6px 12px;
cursor: pointer;
transition: background 120ms ease, border-color 120ms ease, color 120ms ease, box-shadow 120ms ease;
}
button:hover:not(:disabled) { background: var(--bg-subtle); border-color: var(--border-strong); }
button:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
button.primary {
background: var(--accent);
border-color: var(--accent);
color: white;
font-weight: 500;
box-shadow: 0 1px 0 rgba(180, 90, 59, 0.18) inset, var(--shadow-xs);
}
button.primary:hover:not(:disabled) {
background: var(--accent-hover);
border-color: var(--accent-hover);
}
button.primary-ghost {
background: var(--bg-panel);
border-color: var(--accent);
color: var(--accent);
font-weight: 500;
}
button.primary-ghost:hover:not(:disabled) { background: var(--accent-tint); }
button.ghost {
background: transparent;
border-color: var(--border);
color: var(--text);
}
button.ghost:hover:not(:disabled) { background: var(--bg-subtle); border-color: var(--border-strong); }
button.subtle {
background: var(--bg-subtle);
border-color: transparent;
color: var(--text);
}
button.subtle:hover:not(:disabled) { background: var(--bg-muted); }
button.icon-btn { padding: 6px 10px; font-size: 13px; }
button:disabled { opacity: 0.5; cursor: not-allowed; }
/* -------- Inputs ---------------------------------------------------- */
input, textarea, select {
font: inherit;
color: var(--text);
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 7px 10px;
width: 100%;
transition: border-color 120ms ease, box-shadow 120ms ease;
}
input::placeholder, textarea::placeholder { color: var(--text-faint); }
input:focus, textarea:focus, select:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
select { padding-right: 24px; }
textarea { resize: vertical; font-family: inherit; }
code {
font-family: var(--mono);
background: var(--bg-subtle);
padding: 1px 5px;
border-radius: 4px;
font-size: 0.92em;
color: var(--text);
}
/* -------- App shell ------------------------------------------------- */
.app {
display: grid;
grid-template-rows: auto 1fr;
height: 100vh;
background: var(--bg-app);
}
.app-chrome-header {
--app-chrome-traffic-space: 0px;
display: flex;
align-items: center;
height: 40px;
min-height: 40px;
max-height: 40px;
padding: 4px 14px;
border-bottom: 1px solid var(--border);
background: var(--bg);
gap: 12px;
flex-shrink: 0;
}
.app-chrome-traffic-space {
width: var(--app-chrome-traffic-space);
flex: 0 0 var(--app-chrome-traffic-space);
}
.app-chrome-brand {
display: inline-flex;
align-items: center;
gap: 10px;
min-width: 0;
flex-shrink: 0;
}
.app-chrome-mark {
width: 28px;
height: 28px;
border-radius: 0;
display: inline-flex;
align-items: center;
justify-content: center;
background: transparent;
overflow: visible;
flex-shrink: 0;
}
.app-chrome-mark .brand-mark-img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
padding: 0;
user-select: none;
-webkit-user-drag: none;
}
.app-chrome-name {
color: var(--text-strong);
font-size: 18px;
font-weight: 650;
letter-spacing: -0.01em;
white-space: nowrap;
}
.app-chrome-back,
.settings-icon-btn {
width: 32px;
height: 32px;
padding: 0;
border-color: transparent;
background: transparent;
color: var(--text-muted);
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.app-chrome-back:hover:not(:disabled),
.settings-icon-btn:hover:not(:disabled) {
background: var(--bg-subtle);
border-color: var(--border);
color: var(--text);
}
.app-chrome-content {
min-width: 0;
display: flex;
align-items: center;
gap: 10px;
overflow: hidden;
}
.app-chrome-drag {
min-width: 24px;
flex: 1 1 auto;
align-self: stretch;
}
.app-chrome-actions {
display: inline-flex;
align-items: center;
gap: 6px;
flex-shrink: 0;
}
.app-project-title {
display: flex;
flex-direction: column;
gap: 1px;
min-width: 0;
max-height: 31px;
overflow: hidden;
}
.app-project-title .title {
color: var(--text-strong);
font-size: 13.5px;
line-height: 16px;
font-weight: 600;
letter-spacing: -0.01em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.app-project-title .meta {
color: var(--text-muted);
font-size: 11.5px;
line-height: 12px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.topbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 16px;
border-bottom: 1px solid var(--border);
background: var(--bg);
gap: 16px;
flex-wrap: wrap;
}
.topbar-left { display: flex; flex-direction: row; align-items: center; gap: 12px; min-width: 0; }
.topbar-title { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.topbar .title { font-weight: 600; font-size: 14px; letter-spacing: -0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar .meta { color: var(--text-muted); font-size: 11.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-right { display: flex; gap: 6px; align-items: center; flex-wrap: nowrap; }
.topbar .brand-mark {
display: inline-flex;
width: 30px;
height: 30px;
border-radius: 50%;
align-items: center;
justify-content: center;
background: linear-gradient(135deg, var(--accent-tint) 0%, var(--accent-soft) 100%);
color: var(--accent);
flex-shrink: 0;
overflow: hidden;
}
.topbar .brand-mark .brand-mark-img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
padding: 1px;
user-select: none;
-webkit-user-drag: none;
}
.topbar-left .back-btn {
align-self: center;
padding: 4px 10px;
font-size: 12px;
background: transparent;
border-color: transparent;
color: var(--text-muted);
}
.topbar-left .back-btn:hover { background: var(--bg-subtle); color: var(--text); border-color: var(--border); }
/* -------- Avatar menu (replaces in-topbar agent picker) ------------- */
.avatar-menu { position: relative; }
.avatar-btn {
width: 32px;
height: 32px;
padding: 0;
border-radius: 50%;
background: linear-gradient(135deg, var(--accent-tint) 0%, var(--accent-soft) 100%);
border: 1px solid var(--border);
display: inline-flex;
align-items: center;
justify-content: center;
overflow: hidden;
transition: box-shadow 120ms ease, transform 120ms ease;
}
.avatar-btn:hover:not(:disabled) {
box-shadow: 0 0 0 3px rgba(194, 83, 45, 0.18);
border-color: transparent;
}
.avatar-btn:focus-visible {
outline: none;
box-shadow: 0 0 0 3px rgba(194, 83, 45, 0.32);
border-color: transparent;
}
.avatar-btn:active:not(:disabled) { transform: scale(0.96); }
.avatar-btn-photo {
width: 100%;
height: 100%;
object-fit: cover;
object-position: 50% 22%;
display: block;
user-select: none;
-webkit-user-drag: none;
pointer-events: none;
}
.avatar-popover {
position: absolute;
top: calc(100% + 8px);
right: 0;
z-index: 80;
min-width: 280px;
padding: 6px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-lg);
display: flex;
flex-direction: column;
gap: 2px;
}
.avatar-popover-head {
padding: 10px 10px 8px;
display: flex;
flex-direction: column;
gap: 2px;
border-bottom: 1px solid var(--border-soft);
margin-bottom: 4px;
}
.avatar-popover-head .who { font-weight: 600; font-size: 13px; }
.avatar-popover-head .where { font-size: 11.5px; color: var(--text-muted); }
.avatar-item {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
font-size: 12.5px;
text-align: left;
background: transparent;
border: none;
border-radius: var(--radius-sm);
cursor: pointer;
color: var(--text);
}
.avatar-item:hover { background: var(--bg-subtle); }
.avatar-item .avatar-item-icon {
width: 18px; text-align: center; color: var(--text-muted); flex-shrink: 0;
}
.avatar-item .avatar-item-meta {
margin-left: auto;
font-size: 11px;
color: var(--text-muted);
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.avatar-section-label {
font-size: 10.5px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-faint);
font-weight: 600;
padding: 8px 10px 4px;
}
.avatar-model-section {
padding: 2px 10px 6px;
display: flex;
flex-direction: column;
gap: 6px;
border-top: 1px dashed var(--border-soft);
margin-top: 4px;
}
.avatar-select-row {
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: var(--text-muted);
}
.avatar-select-label {
flex-shrink: 0;
min-width: 64px;
}
.avatar-select {
flex: 1;
min-width: 0;
font-size: 12px;
padding: 4px 6px;
border-radius: var(--radius-sm);
border: 1px solid var(--border);
background: var(--bg-panel);
color: var(--text);
cursor: pointer;
}
.avatar-select:focus { outline: 2px solid var(--accent-soft, var(--border-strong)); }
/* Environment pill — only used in entry view header now */
.env-pill {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 4px 12px 4px 4px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-pill);
cursor: pointer;
max-width: 360px;
min-width: 0;
font: inherit;
color: inherit;
}
.env-pill:hover { background: var(--bg-panel); border-color: var(--border-strong); }
.env-pill-dot {
width: 22px; height: 22px; border-radius: 50%;
background: linear-gradient(135deg, #d97757 0%, #b85a3b 100%);
flex-shrink: 0;
}
.env-pill-dot[data-mode="api"] {
background: linear-gradient(135deg, #1c1b1a 0%, #4b4948 100%);
}
.env-pill-label { font-weight: 500; font-size: 12px; }
.env-pill-meta {
font-size: 12px; color: var(--text-muted);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
/* -------- Split / panes -------------------------------------------- */
.split {
display: grid;
grid-template-columns: 460px 8px minmax(400px, 1fr);
min-height: 0;
min-width: 0;
}
.split.is-resizing-chat {
cursor: col-resize;
user-select: none;
}
.split.is-resizing-chat iframe {
pointer-events: none;
}
.split.split-focus {
grid-template-columns: minmax(0, 1fr);
}
.split-chat-slot {
display: flex;
min-height: 0;
min-width: 0;
}
.split-chat-slot[hidden] {
display: none;
}
.split-chat-slot > .pane {
flex: 1 1 auto;
}
.pane {
display: flex;
flex-direction: column;
min-height: 0;
min-width: 0;
background: var(--bg-panel);
}
.split-resize-handle {
width: 8px;
min-width: 8px;
height: 100%;
cursor: col-resize;
background:
linear-gradient(
90deg,
transparent 0,
transparent 3px,
var(--border) 3px,
var(--border) 5px,
transparent 5px
);
transition: background 120ms ease;
touch-action: none;
}
.split-resize-handle:hover,
.split-resize-handle:focus-visible,
.split.is-resizing-chat .split-resize-handle {
background:
linear-gradient(
90deg,
color-mix(in srgb, var(--accent) 16%, transparent) 0,
color-mix(in srgb, var(--accent) 16%, transparent) 3px,
var(--accent) 3px,
var(--accent) 5px,
color-mix(in srgb, var(--accent) 16%, transparent) 5px
);
}
.split-resize-handle:focus-visible {
outline: 2px solid var(--accent);
outline-offset: -2px;
}
/* -------- Chat sticky header --------------------------------------- */
.chat-header {
display: flex;
align-items: center;
gap: 4px;
padding: 8px 12px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
position: sticky;
top: 0;
z-index: 4;
height: 44px;
}
.chat-header-tabs { display: inline-flex; gap: 16px; flex: 1; }
.chat-header-tab {
background: transparent;
border: none;
border-bottom: 2px solid transparent;
border-radius: 0;
padding: 8px 0;
font-size: 13px;
color: var(--text-muted);
font-weight: 500;
}
.chat-header-tab:hover { color: var(--text); background: transparent; border-color: transparent; }
.chat-header-tab.active {
color: var(--text);
border-bottom-color: var(--text);
}
.chat-header-actions { display: inline-flex; gap: 4px; align-items: center; }
.chat-header-actions .icon-only {
width: 28px; height: 28px;
padding: 0;
background: transparent;
border: none;
border-radius: 6px;
color: var(--text-muted);
display: inline-flex;
align-items: center;
justify-content: center;
}
.chat-header-actions .icon-only:hover { background: var(--bg-subtle); color: var(--text); }
.chat-log {
flex: 1;
overflow-y: auto;
padding: 16px;
display: flex;
flex-direction: column;
gap: 14px;
min-width: 0;
}
/* -------- Messages -------------------------------------------------- */
.msg {
padding: 0;
background: transparent;
border: none;
white-space: normal;
word-wrap: break-word;
}
.msg .role {
display: flex;
align-items: baseline;
gap: 8px;
font-size: 12.5px;
text-transform: none;
color: var(--text-strong);
margin-bottom: 4px;
letter-spacing: 0;
font-weight: 600;
}
.msg-time {
color: var(--text-faint);
font-size: 11px;
font-weight: 500;
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.chat-day-separator {
display: flex;
align-items: center;
gap: 10px;
color: var(--text-faint);
font-size: 11px;
font-weight: 600;
margin: 4px 0 0;
}
.chat-day-separator::before,
.chat-day-separator::after {
content: '';
height: 1px;
background: var(--border);
flex: 1;
}
.msg.user .role::before { content: ''; }
.msg.user .user-text { white-space: pre-wrap; color: var(--text); }
.msg.assistant .prose { margin-top: 4px; }
.msg .artifact-badge {
display: inline-block;
margin-top: 8px;
padding: 2px 8px;
font-size: 11px;
background: var(--accent);
color: white;
border-radius: 4px;
}
.msg.error {
border: 1px solid var(--red-border);
background: var(--red-bg);
color: var(--red);
padding: 10px 12px;
border-radius: var(--radius-sm);
}
/* -------- Composer -------------------------------------------------- */
.composer {
border-top: 1px solid var(--border);
padding: 10px;
display: flex;
flex-direction: column;
gap: 8px;
background: var(--bg-panel);
}
.composer-shell {
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-panel);
box-shadow: var(--shadow-xs);
padding: 8px 10px 6px;
display: flex;
flex-direction: column;
gap: 6px;
transition: border-color 120ms ease, box-shadow 120ms ease;
}
.composer-shell:focus-within {
border-color: var(--border-strong);
box-shadow: var(--shadow-sm);
}
.composer.drag-active .composer-shell {
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.composer textarea {
min-height: 60px;
border: none;
background: transparent;
padding: 4px 4px;
resize: vertical;
}
.composer textarea:focus { outline: none; box-shadow: none; }
.composer-input-wrap { position: relative; }
.composer-row {
display: flex;
align-items: center;
gap: 6px;
padding-top: 4px;
}
.composer-row .icon-btn {
width: 28px; height: 28px;
padding: 0;
background: transparent;
border: none;
border-radius: 6px;
color: var(--text-muted);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
.composer-row .icon-btn:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); }
.composer-spacer { flex: 1; }
.composer-import {
background: transparent;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 4px 12px;
font-size: 12px;
color: var(--text-muted);
}
.composer-import:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); }
.composer-send {
display: inline-flex;
align-items: center;
gap: 6px;
background: var(--accent);
border-color: var(--accent);
color: white;
font-weight: 500;
padding: 4px 14px;
font-size: 12.5px;
}
.composer-send:hover:not(:disabled) { background: var(--accent-hover); border-color: var(--accent-hover); }
.composer-send.stop { background: var(--text); border-color: var(--text); color: var(--bg); }
.composer-send.stop:hover { background: var(--text-strong); border-color: var(--text-strong); color: var(--bg); }
.composer-hint {
font-size: 11px;
color: var(--text-faint);
margin: 0 8px;
}
/* -------- Staged attachments -------------------------------------- */
.staged-row {
display: flex;
flex-wrap: wrap;
gap: 6px;
padding: 4px 4px 0;
}
.staged-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 8px 4px 4px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
max-width: 220px;
font-size: 11.5px;
box-shadow: var(--shadow-xs);
}
.staged-chip img {
width: 28px;
height: 28px;
border-radius: 6px;
object-fit: cover;
}
.staged-comment {
max-width: 280px;
border-radius: var(--radius-pill);
padding: 4px 6px 4px 10px;
}
.staged-comment .staged-name {
display: inline-flex;
align-items: center;
gap: 6px;
min-width: 0;
}
.staged-comment .staged-name strong {
color: var(--accent-strong);
font-weight: 650;
flex: 0 0 auto;
}
.staged-comment .staged-name span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.staged-comment button {
width: 20px;
height: 20px;
padding: 0;
border: 0;
border-radius: var(--radius-pill);
background: transparent;
color: var(--text-faint);
font-size: 14px;
line-height: 1;
}
.staged-comment button:hover {
background: var(--bg-subtle);
color: var(--text);
}
.staged-icon {
width: 28px; height: 28px;
border-radius: 6px;
background: var(--bg-subtle);
color: var(--text-muted);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
.staged-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 140px;
color: var(--text);
}
.staged-remove {
background: transparent;
border: none;
padding: 0 2px;
color: var(--text-faint);
cursor: pointer;
font-size: 13px;
line-height: 1;
border-radius: 4px;
}
.staged-remove:hover { color: var(--red); background: var(--red-bg); }
.linked-dirs-row {
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.linked-dir-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
font-size: 11.5px;
color: var(--text-muted);
max-width: 220px;
}
.linked-dir-chip svg { flex-shrink: 0; color: var(--text-muted); }
.linked-dir-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.composer-import-item-enabled {
cursor: pointer;
color: var(--text);
}
.composer-import-item-enabled:hover {
background: var(--bg-subtle);
color: var(--text);
}
.user-attachments {
display: flex;
gap: 6px;
flex-wrap: wrap;
margin-bottom: 8px;
}
.user-attachment {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 4px 10px 4px 4px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
font-size: 11.5px;
max-width: 240px;
color: var(--text);
cursor: default;
text-align: left;
font: inherit;
font-size: 11.5px;
}
.user-attachment.openable { cursor: pointer; }
.user-attachment.openable:hover {
background: var(--bg-subtle);
border-color: var(--accent);
}
.user-attachment img {
width: 28px;
height: 28px;
object-fit: cover;
border-radius: 6px;
display: block;
}
.user-attachment .staged-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* -------- Mention popover ------------------------------------------- */
.mention-popover {
position: absolute;
bottom: 100%;
left: 0;
right: 0;
margin-bottom: 4px;
max-height: 220px;
overflow-y: auto;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
z-index: 10;
}
.mention-item {
display: flex;
align-items: center;
width: 100%;
background: transparent;
border: none;
padding: 7px 10px;
font-size: 12px;
text-align: left;
gap: 8px;
}
.mention-item:hover { background: var(--bg-subtle); border-color: transparent; }
.mention-item code {
flex: 1;
font-size: 11px;
background: transparent;
padding: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.mention-meta { color: var(--text-muted); font-size: 10px; flex-shrink: 0; }
/* ===========================================================
Modal / Settings
=========================================================== */
.modal-backdrop {
position: fixed; inset: 0;
background: rgba(28, 27, 26, 0.42);
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
display: flex;
align-items: center;
justify-content: center;
z-index: 100;
animation: fade-in 160ms ease-out;
}
.modal {
background: var(--bg-elevated);
border-radius: var(--radius-lg);
padding: 22px;
width: 520px;
max-width: calc(100vw - 32px);
display: flex;
flex-direction: column;
gap: 12px;
box-shadow: var(--shadow-lg);
animation: pop-in 220ms cubic-bezier(0.21, 1.02, 0.73, 1);
}
.modal h2 { margin: 0; font-size: 18px; letter-spacing: -0.01em; font-weight: 600; }
.modal label {
display: flex;
flex-direction: column;
gap: 4px;
font-size: 12px;
color: var(--text-muted);
}
.modal .hint {
font-size: 12px;
color: var(--text-muted);
line-height: 1.55;
margin: 0;
}
.modal .row { display: flex; justify-content: flex-end; gap: 8px; margin-top: 4px; }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes pop-in {
from { opacity: 0; transform: translateY(6px) scale(0.98); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
@keyframes pulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.6; transform: scale(0.85); }
}
.modal-settings {
--modal-padding: 24px;
width: min(920px, calc(100vw - 48px));
padding: 0;
gap: 0;
max-height: calc(100vh - 64px);
}
@media (max-height: 600px) {
.modal-settings { max-height: 90vh; }
}
.modal-settings .modal-body {
overflow: hidden;
flex: 1;
min-height: 0;
display: grid;
grid-template-columns: 240px minmax(0, 1fr);
gap: 0;
margin: 0;
padding: 0;
border-top: 1px solid var(--border);
}
.modal-head {
display: flex;
flex-direction: column;
gap: 4px;
flex-shrink: 0;
padding: var(--modal-padding);
}
.modal-head .kicker {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--accent);
font-weight: 600;
}
.modal-head h2 {
font-size: 22px;
font-weight: 600;
letter-spacing: -0.015em;
color: var(--text);
}
.modal-head .subtitle {
margin: 4px 0 0;
font-size: 13px;
color: var(--text-muted);
line-height: 1.55;
max-width: 50ch;
}
.modal-foot {
display: flex;
justify-content: flex-end;
gap: 8px;
padding: 12px var(--modal-padding);
border-top: 1px solid var(--border);
margin-top: 0;
flex-shrink: 0;
}
.settings-sidebar {
display: flex;
flex-direction: column;
gap: 8px;
padding: 22px 12px;
background: var(--bg-subtle);
border-right: 1px solid var(--border);
min-height: 0;
overflow-y: auto;
overscroll-behavior: contain;
}
.settings-nav-item {
width: 100%;
border: 1px solid transparent;
border-radius: 12px;
background: transparent;
color: var(--text-muted);
display: grid;
grid-template-columns: 24px minmax(0, 1fr);
gap: 10px;
align-items: center;
padding: 12px;
text-align: left;
cursor: pointer;
}
.settings-nav-item:hover {
background: color-mix(in srgb, var(--bg-panel) 72%, transparent);
color: var(--text);
}
.settings-nav-item.active {
background: var(--bg-panel);
border-color: color-mix(in srgb, var(--accent) 62%, var(--border));
color: var(--text);
box-shadow: var(--shadow-xs);
}
.settings-nav-item svg {
justify-self: center;
}
.settings-nav-item span {
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.settings-nav-item strong {
color: currentColor;
font-size: 13px;
font-weight: 650;
line-height: 1.2;
overflow-wrap: anywhere;
}
.settings-nav-item small {
color: var(--text-muted);
font-size: 11px;
line-height: 1.25;
overflow-wrap: anywhere;
}
.settings-content {
min-width: 0;
min-height: 0;
padding: 22px var(--modal-padding);
overflow: auto;
overscroll-behavior: contain;
display: flex;
flex-direction: column;
gap: 18px;
}
@media (max-width: 760px) {
.modal-settings {
width: min(560px, calc(100vw - 24px));
}
.modal-settings .modal-body {
grid-template-columns: 1fr;
}
.settings-sidebar {
flex-direction: row;
overflow-x: auto;
overscroll-behavior-x: contain;
padding: 10px 12px;
border-right: 0;
border-bottom: 1px solid var(--border);
}
.settings-nav-item {
min-width: 150px;
}
}
/* Segmented control */
.seg-control {
display: grid;
grid-template-columns: repeat(var(--seg-cols, 2), minmax(0, 1fr));
gap: 6px;
padding: 4px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
min-width: 0;
}
.seg-btn {
display: flex;
flex-direction: column;
gap: 2px;
align-items: flex-start;
padding: 10px 14px;
border: 1px solid transparent;
border-radius: 10px;
background: transparent;
cursor: pointer;
text-align: left;
min-width: 0;
}
.seg-btn:hover:not(:disabled):not(.active) { background: rgba(255, 255, 255, 0.5); }
.seg-btn.active {
background: var(--bg-panel);
border-color: var(--border-strong);
box-shadow: var(--shadow-sm);
}
.seg-btn .seg-title { font-size: 13px; font-weight: 600; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.seg-btn .seg-meta { font-size: 11px; color: var(--text-muted); letter-spacing: 0.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.seg-btn:disabled { opacity: 0.55; cursor: not-allowed; }
/* Secondary protocol selector — pill chips, wraps to multiple rows */
.protocol-chips {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin: 4px 0 8px;
padding: 0;
min-width: 0;
}
.protocol-chip {
flex: 0 1 auto;
max-width: 100%;
min-width: 0;
background: transparent;
border: 1px solid var(--border);
border-radius: 999px;
padding: 6px 12px;
font-size: 13px;
font-weight: 500;
color: var(--text-muted);
cursor: pointer;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
transition: background 120ms ease, color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}
.protocol-chip:hover:not(.active) {
background: var(--bg-subtle);
color: var(--text);
border-color: var(--border-strong);
}
.protocol-chip.active {
background: linear-gradient(180deg, var(--bg-panel) 0%, var(--accent-tint) 100%);
border-color: var(--accent);
color: var(--text);
font-weight: 600;
box-shadow: 0 0 0 2px var(--accent-soft);
}
.settings-section { display: flex; flex-direction: column; gap: 12px; }
.settings-rescan-btn {
display: inline-flex;
align-items: center;
gap: 6px;
min-width: 96px;
justify-content: center;
}
.settings-rescan-btn.loading {
border-color: var(--accent-soft);
background: var(--accent-tint);
color: var(--accent-strong);
}
.settings-rescan-status {
margin: -4px 0 0;
padding: 7px 10px;
border: 1px solid var(--green-border);
border-radius: var(--radius-sm);
background: var(--green-bg);
color: var(--green);
font-size: 12px;
line-height: 1.4;
}
.settings-rescan-status.error {
border-color: var(--red-border);
background: var(--red-bg);
color: var(--red);
}
.settings-field-error {
color: var(--red);
font-size: 12px;
line-height: 1.4;
}
.settings-about-list {
margin: 0;
display: flex;
flex-direction: column;
gap: 8px;
}
.settings-about-list > div {
display: flex;
justify-content: space-between;
gap: 16px;
padding: 12px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
}
.settings-about-list dt {
font-size: 12px;
color: var(--text-muted);
}
.settings-about-list dd {
margin: 0;
color: var(--text);
font-size: 13px;
font-weight: 600;
text-align: right;
overflow-wrap: anywhere;
}
.media-provider-list {
display: flex;
flex-direction: column;
gap: 10px;
}
.media-provider-row {
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
}
.media-provider-row.pending {
background: var(--bg-subtle);
border-style: dashed;
}
.media-provider-head {
display: flex;
justify-content: space-between;
gap: 10px;
}
.media-provider-meta {
display: flex;
flex-direction: column;
gap: 2px;
}
.media-provider-name {
font-size: 13px;
font-weight: 600;
color: var(--text);
}
.media-provider-hint {
font-size: 11px;
color: var(--text-muted);
}
.media-provider-badge {
align-self: flex-start;
font-size: 10px;
font-weight: 600;
padding: 2px 7px;
border-radius: var(--radius-pill);
border: 1px solid var(--border);
}
.media-provider-badges {
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 6px;
}
.media-provider-badge.integrated {
color: #137a3d;
background: color-mix(in srgb, #1f9d55 10%, transparent);
border-color: color-mix(in srgb, #1f9d55 28%, var(--border));
}
.media-provider-badge.unsupported {
color: var(--text-soft);
background: var(--bg-subtle);
border-color: var(--border);
}
.media-provider-badge.on {
color: #3155c9;
background: color-mix(in srgb, #4169e1 10%, transparent);
border-color: color-mix(in srgb, #4169e1 28%, var(--border));
}
.media-provider-body {
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
gap: 6px;
}
.section-head {
display: flex;
justify-content: space-between;
align-items: flex-start;
gap: 12px;
}
.section-head > div {
max-width: 100%;
min-width: 0;
}
.section-head h3 { margin: 0; font-size: 13px; font-weight: 600; letter-spacing: 0.01em; }
.section-head .hint { margin-top: 2px; }
.field { display: flex; flex-direction: column; gap: 4px; }
.field-label { font-size: 12px; font-weight: 500; color: var(--text-muted); }
.field-row { display: flex; gap: 6px; align-items: stretch; }
.field-row input { flex: 1; }
.field-row .icon-btn { white-space: nowrap; padding: 6px 12px; }
.settings-language-picker { position: relative; }
.settings-language-button {
width: 100%;
display: grid;
grid-template-columns: auto 1fr auto;
align-items: center;
gap: 12px;
padding: 12px 14px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
color: var(--text);
text-align: left;
box-shadow: none;
}
.settings-language-button:hover {
border-color: var(--border-strong);
box-shadow: var(--shadow-sm);
}
.settings-language-button[aria-expanded="true"] {
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.settings-language-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 42px;
height: 42px;
border-radius: 12px;
background: linear-gradient(135deg, var(--bg-panel) 0%, var(--bg-subtle) 100%);
border: 1px solid var(--border);
color: var(--accent);
flex-shrink: 0;
}
.settings-language-text,
.settings-language-option > span:first-child {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.settings-language-title,
.settings-language-option-title {
font-size: 13px;
font-weight: 600;
color: var(--text);
overflow-wrap: anywhere;
}
.settings-language-code,
.settings-language-option-code {
font-size: 11px;
color: var(--text-muted);
font-variant-numeric: tabular-nums;
letter-spacing: 0.02em;
}
.settings-language-menu {
position: fixed;
z-index: 1000;
max-width: calc(100vw - 24px);
/* 7 locales × ~58px + menu chrome (padding, gap, border) ≈ 428px;
--menu-available-h is set by JS to the distance between the trigger
and whichever viewport edge the menu opens toward, so the menu never
overflows the viewport regardless of placement direction. The 60vh
cap keeps the menu from feeling cramped on short viewports. */
max-height: min(428px, 60vh, var(--menu-available-h, 428px));
overflow-y: auto;
overscroll-behavior: contain;
display: flex;
flex-direction: column;
gap: 2px;
padding: 4px;
background: var(--bg-panel);
border: 1px solid var(--border-strong);
border-radius: var(--radius-sm);
box-shadow: 0 14px 30px rgba(0, 0, 0, 0.14);
}
.settings-language-option {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
gap: 12px;
width: 100%;
padding: 10px 12px;
border: 0;
border-radius: 9px;
background: transparent;
text-align: left;
color: var(--text);
}
.settings-language-option:hover,
.settings-language-option.active { background: var(--bg-subtle); }
.settings-language-option.active { color: var(--accent); }
.empty-card {
padding: 16px;
border: 1px dashed var(--border);
border-radius: var(--radius-sm);
color: var(--text-muted);
font-size: 12px;
background: var(--bg-subtle);
}
.agent-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 8px;
}
.agent-card {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
text-align: left;
position: relative;
transition: border-color 120ms ease, transform 120ms ease, box-shadow 120ms ease, background 120ms ease;
}
.agent-card:hover:not(.disabled) {
border-color: var(--border-strong);
transform: translateY(-1px);
box-shadow: var(--shadow-sm);
}
.agent-card.active {
border-color: var(--accent);
background: linear-gradient(180deg, var(--bg-panel) 0%, var(--accent-tint) 100%);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.agent-card.disabled {
cursor: not-allowed;
opacity: 0.55;
background: var(--bg-subtle);
}
.agent-card-body { display: flex; flex-direction: column; min-width: 0; flex: 1; }
.agent-card-name {
font-size: 13px; font-weight: 600; color: var(--text);
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.agent-card-meta {
font-size: 11px; color: var(--text-muted);
font-variant-numeric: tabular-nums;
white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.agent-card-meta .muted { color: var(--text-soft); font-style: italic; }
.agent-model-row {
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px;
border: 1px solid var(--border-soft);
border-radius: var(--radius-sm);
background: var(--bg-subtle);
}
.agent-model-row .field { gap: 4px; }
.agent-model-row .field-label {
font-size: 11.5px;
text-transform: uppercase;
letter-spacing: 0.04em;
color: var(--text-muted);
}
.agent-model-row .hint { margin: 0; font-size: 11.5px; }
.agent-cli-env {
display: flex;
flex-direction: column;
gap: 8px;
padding: 12px;
border: 1px solid var(--border-soft);
border-radius: var(--radius-sm);
background: var(--bg-panel);
}
.agent-cli-env-head {
display: flex;
flex-direction: column;
gap: 2px;
}
.agent-cli-env-head h4 {
margin: 0;
font-size: 12px;
font-weight: 600;
color: var(--text);
}
.agent-cli-env-head .hint { margin: 0; font-size: 11.5px; }
.agent-cli-env-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
}
.status-dot {
width: 8px; height: 8px;
border-radius: 50%;
background: #cbd5e1;
flex-shrink: 0;
}
.status-dot.active {
background: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.agent-icon {
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.06), 0 1px 2px rgba(0, 0, 0, 0.08);
}
.error {
border-color: var(--red-border);
background: var(--red-bg);
color: var(--red);
}
/* ===========================================================
Activity ticker (legacy — still used in some flows)
=========================================================== */
.activity {
margin: 4px 0 8px;
padding: 8px 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg-subtle);
}
.activity-header { display: flex; align-items: center; gap: 8px; font-size: 12px; margin-bottom: 6px; }
.activity-header .dot {
width: 8px; height: 8px;
border-radius: 50%;
background: var(--text-muted);
flex: 0 0 auto;
}
.activity-header .dot[data-active="true"] {
background: var(--accent);
animation: pulse 1.2s ease-in-out infinite;
}
.activity-title { font-weight: 500; }
.activity-stats {
margin-left: auto;
color: var(--text-muted);
font-variant-numeric: tabular-nums;
font-size: 11px;
}
.activity-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 4px;
max-height: 280px;
overflow-y: auto;
}
.activity-item {
display: flex;
align-items: flex-start;
gap: 8px;
font-size: 12px;
line-height: 1.4;
padding: 2px 0;
}
.activity-item .badge {
flex: 0 0 auto;
display: inline-block;
padding: 1px 6px;
border-radius: 4px;
font-size: 10px;
font-weight: 500;
letter-spacing: 0.02em;
background: var(--bg-subtle);
color: var(--text-muted);
border: 1px solid var(--border);
min-width: 56px;
text-align: center;
}
.activity-item .badge-tool { background: var(--blue-bg); border-color: var(--blue-border); color: var(--blue); }
.activity-item .badge-result { background: var(--green-bg); border-color: var(--green-border); color: var(--green); }
.activity-item .badge-error,
.activity-item .badge-result.badge-error {
background: var(--red-bg); border-color: var(--red-border); color: var(--red);
}
.activity-item .badge-thinking { background: var(--purple-bg); border-color: var(--purple-border); color: var(--purple); }
.activity-item .badge-status { background: var(--bg-panel); }
.activity-item .badge-text { background: transparent; border-color: var(--border); }
.activity-item .badge-usage { background: var(--bg-panel); color: var(--text-muted); }
.activity-item .detail { flex: 1; min-width: 0; overflow-wrap: break-word; word-break: break-word; }
.activity-item .detail.muted { color: var(--text-muted); }
.activity-item .thinking-text { font-style: italic; color: var(--text-muted); }
.activity-waiting { font-size: 11px; color: var(--text-muted); font-style: italic; }
/* ============================================================
Entry view — left sidebar + right tabs
============================================================ */
.entry-shell {
display: grid;
grid-template-rows: auto 1fr;
height: 100vh;
min-height: 0;
background: var(--bg);
}
.entry {
display: grid;
grid-template-columns: 380px 1fr;
height: 100%;
min-height: 0;
background: var(--bg);
}
.entry-side {
border-right: 1px solid var(--border);
background: var(--bg-panel);
padding: 28px 24px 20px;
display: flex;
flex-direction: column;
gap: 20px;
overflow-y: auto;
}
.entry-brand {
display: flex;
align-items: center;
gap: 12px;
}
.entry-brand-mark {
width: 44px;
height: 44px;
border-radius: 50%;
background: linear-gradient(135deg, var(--accent-tint) 0%, var(--accent-soft) 100%);
color: var(--accent);
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
overflow: hidden;
}
.entry-brand-mark .brand-mark-img {
width: 100%;
height: 100%;
object-fit: contain;
display: block;
padding: 2px;
user-select: none;
-webkit-user-drag: none;
}
.entry-brand-text { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.entry-brand-title-row {
display: flex;
align-items: center;
gap: 8px;
}
.entry-brand-title {
font-family: var(--serif);
font-weight: 600;
font-size: 22px;
letter-spacing: -0.015em;
line-height: 1;
color: var(--text-strong);
}
.entry-brand-pill {
font-size: 10.5px;
letter-spacing: 0.02em;
padding: 2px 8px;
border-radius: var(--radius-pill);
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
}
.entry-brand-subtitle {
font-size: 11.5px;
color: var(--text-muted);
letter-spacing: 0.01em;
}
/* New project panel */
.newproj {
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-panel);
display: flex;
flex-direction: column;
box-shadow: var(--shadow-xs);
}
.newproj-tabs-shell {
position: relative;
border-bottom: 1px solid var(--border);
overflow: hidden;
}
.newproj-tabs {
display: flex;
padding: 4px 4px 0;
gap: 2px;
overflow-x: auto;
overflow-y: hidden;
scroll-behavior: smooth;
scrollbar-width: none;
}
.newproj-tabs::-webkit-scrollbar { display: none; }
.newproj-tabs-shell::before,
.newproj-tabs-shell::after {
content: '';
position: absolute;
top: 0;
bottom: 0;
width: 28px;
z-index: 1;
pointer-events: none;
opacity: 0;
transition: opacity 120ms ease;
}
.newproj-tabs-shell::before {
left: 0;
background: linear-gradient(90deg, var(--bg-panel), transparent);
}
.newproj-tabs-shell::after {
right: 0;
background: linear-gradient(270deg, var(--bg-panel), transparent);
}
.newproj-tabs-shell.can-left::before,
.newproj-tabs-shell.can-right::after {
opacity: 1;
}
.newproj-tabs-arrow {
position: absolute;
top: 50%;
z-index: 2;
width: 28px;
height: 28px;
transform: translateY(-50%);
border: 1px solid var(--border);
border-radius: 999px;
background: var(--bg-panel);
color: var(--text-strong);
box-shadow: var(--shadow-xs);
display: inline-flex;
align-items: center;
justify-content: center;
padding: 0;
transition: opacity 120ms ease, transform 120ms ease;
}
.newproj-tabs-arrow:hover { border-color: var(--border-strong); background: var(--bg-subtle); }
.newproj-tabs-arrow svg {
display: block;
flex: none;
}
.newproj-tabs-arrow.left { left: 6px; }
.newproj-tabs-arrow.right { right: 6px; }
.newproj-tabs-arrow.hidden {
opacity: 0;
pointer-events: none;
transform: translateY(-50%) scale(0.92);
}
.newproj-tab {
flex: 0 0 auto;
min-width: max-content;
padding: 10px 6px;
border: none;
background: transparent;
font-size: 12px;
border-radius: 6px 6px 0 0;
color: var(--text-muted);
border-bottom: 2px solid transparent;
font-weight: 500;
}
.newproj-tab:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); }
.newproj-tab.active {
color: var(--text);
border-bottom-color: var(--text);
}
.newproj-body {
padding: 18px;
display: flex;
flex-direction: column;
gap: 14px;
}
.newproj-title {
margin: 0;
font-size: 14px;
font-weight: 600;
display: flex;
align-items: center;
gap: 8px;
}
.newproj-title-text { flex: 1 1 auto; min-width: 0; }
.newproj-title-badge {
flex: 0 0 auto;
display: inline-flex;
align-items: center;
padding: 2px 8px;
border-radius: var(--radius-pill);
border: 1px solid color-mix(in srgb, var(--accent) 32%, var(--border));
background: color-mix(in srgb, var(--accent) 12%, var(--bg-panel));
color: var(--accent);
font-size: 10px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
line-height: 1.4;
}
.newproj-name { width: 100%; }
.newproj-section { display: flex; flex-direction: column; gap: 6px; }
.newproj-label {
font-size: 11.5px;
color: var(--text-muted);
font-weight: 500;
}
.newproj-media-options {
display: flex;
flex-direction: column;
gap: 14px;
}
.newproj-media-field,
.newproj-media-options .newproj-label {
display: flex;
flex-direction: column;
gap: 6px;
}
.newproj-model-groups {
display: flex;
flex-direction: column;
gap: 12px;
}
.newproj-model-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.newproj-provider-row {
display: flex;
align-items: center;
gap: 8px;
color: var(--text-muted);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.11em;
text-transform: uppercase;
}
.newproj-provider-badge {
border-radius: 999px;
padding: 2px 8px;
font-size: 10px;
letter-spacing: 0.08em;
}
.newproj-provider-badge.configured {
border: 1px solid color-mix(in srgb, #4169e1 24%, transparent);
background: color-mix(in srgb, #4169e1 10%, transparent);
color: #3155c9;
}
.newproj-provider-badge.integrated {
border: 1px solid color-mix(in srgb, var(--accent) 24%, transparent);
background: color-mix(in srgb, var(--accent) 10%, transparent);
color: color-mix(in srgb, var(--accent) 78%, var(--text-strong));
}
.newproj-provider-badge.unsupported {
border: 1px solid var(--border);
background: var(--bg-subtle);
color: var(--text-muted);
}
.newproj-model-grid,
.newproj-option-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 8px;
}
.newproj-option-grid.aspect-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
.newproj-option-grid.compact {
grid-template-columns: repeat(auto-fit, minmax(92px, 1fr));
}
.newproj-card {
border: 1px solid var(--border);
border-radius: 10px;
background: var(--bg-panel);
color: var(--text-strong);
box-shadow: var(--shadow-xs);
cursor: pointer;
text-align: left;
transition: border-color 140ms ease, background 140ms ease, box-shadow 140ms ease;
}
.newproj-card:hover {
border-color: var(--border-strong);
background: var(--bg-subtle);
}
.newproj-card.active {
border-color: var(--accent);
background: color-mix(in srgb, var(--accent) 9%, var(--bg-panel));
box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 26%, transparent);
}
.newproj-model-card {
min-height: 74px;
padding: 12px;
display: flex;
flex-direction: column;
gap: 5px;
}
.newproj-model-name {
font-family: var(--font-mono);
font-size: 14px;
font-weight: 700;
line-height: 1.2;
}
.newproj-model-hint {
color: var(--text-muted);
font-size: 12px;
line-height: 1.35;
}
.newproj-option-card {
min-height: 62px;
min-width: 0;
padding: 10px;
display: flex;
align-items: center;
justify-content: center;
gap: 7px;
text-align: center;
color: var(--text-muted);
font-size: 12px;
font-weight: 600;
}
.newproj-option-card small {
color: var(--text-muted);
font-size: 11px;
}
.aspect-grid .newproj-option-card {
flex-direction: column;
gap: 6px;
padding: 10px 6px;
}
.aspect-copy {
display: flex;
flex-direction: column;
gap: 2px;
align-items: center;
line-height: 1.15;
min-width: 0;
max-width: 100%;
}
.aspect-copy strong {
color: var(--text-muted);
font-size: 12.5px;
font-weight: 650;
letter-spacing: -0.005em;
max-width: 100%;
overflow-wrap: anywhere;
}
.aspect-copy small {
color: var(--text-muted);
font-size: 11.5px;
}
.aspect-glyph {
flex: none;
width: 34px;
height: 24px;
border-radius: 4px;
background: var(--bg-subtle);
box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--border) 80%, transparent);
}
.aspect-1-1 { width: 22px; height: 22px; }
.aspect-16-9 { width: 32px; height: 18px; }
.aspect-9-16 { width: 18px; height: 32px; }
.aspect-4-3 { width: 28px; height: 21px; }
.aspect-3-4 { width: 21px; height: 28px; }
@media (max-width: 560px) {
.newproj-model-grid,
.newproj-option-grid,
.newproj-option-grid.aspect-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
.newproj-skills {
display: flex;
flex-direction: column;
gap: 6px;
max-height: 220px;
overflow-y: auto;
padding-right: 4px;
}
.skill-radio {
display: flex;
gap: 8px;
padding: 10px 12px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
align-items: flex-start;
background: var(--bg-panel);
}
.skill-radio:hover { background: var(--bg-subtle); border-color: var(--border-strong); }
.skill-radio.active {
border-color: var(--accent);
background: var(--accent-tint);
}
.skill-radio input { width: auto; margin-top: 2px; }
.skill-radio-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.skill-radio-name { font-weight: 500; font-size: 13px; }
.skill-radio-desc { font-size: 11px; color: var(--text-muted); line-height: 1.4; }
.newproj-empty {
font-size: 12px; color: var(--text-muted);
font-style: italic; padding: 8px 0;
}
.video-body,
.audio-body {
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
background: var(--bg-subtle);
flex: 1;
min-height: 0;
}
.video-body video {
max-width: 100%;
max-height: 100%;
border-radius: var(--radius-sm);
background: #000;
}
.audio-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
width: min(100%, 480px);
padding: 28px 32px;
color: var(--text-muted);
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
}
.audio-card-name {
font-size: 13px;
font-weight: 500;
color: var(--text);
text-align: center;
word-break: break-word;
}
.audio-card audio {
width: 100%;
}
.newproj-create {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
padding: 11px;
margin-top: 4px;
font-size: 13px;
border-radius: var(--radius-sm);
}
.newproj-import {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
width: 100%;
padding: 10px;
font-size: 12.5px;
border-radius: var(--radius-sm);
}
.newproj-create svg,
.newproj-import svg {
display: block;
flex: 0 0 auto;
}
.newproj-footer {
padding: 0 18px 16px;
font-size: 11px;
color: var(--text-muted);
text-align: center;
}
/* -------- Fidelity cards (prototype tab) ---------------------------- */
.fidelity-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 8px;
}
.fidelity-card {
position: relative;
display: flex;
flex-direction: column;
align-items: stretch;
gap: 8px;
padding: 10px 10px 12px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
transition: border-color 120ms ease, box-shadow 120ms ease, background 120ms ease;
}
.fidelity-card:hover { border-color: var(--border-strong); }
.fidelity-card.active {
border-color: var(--accent);
box-shadow:
0 0 0 1px var(--accent),
0 1px 0 rgba(180, 90, 59, 0.04);
}
.fidelity-thumb {
display: block;
width: 100%;
aspect-ratio: 12 / 7;
border-radius: 4px;
overflow: hidden;
background: var(--bg-subtle);
border: 1px solid var(--border-soft);
}
.fidelity-thumb-wireframe { background: #fbfaf6; }
.fidelity-thumb-high-fidelity { background: var(--bg-panel); }
.fidelity-card.active .fidelity-thumb { border-color: var(--accent-soft); }
.fidelity-label {
text-align: center;
font-size: 12px;
font-weight: 500;
color: var(--text);
}
/* -------- Toggle row (deck "speaker notes", template "animations") -- */
.toggle-row {
display: flex;
align-items: center;
gap: 12px;
width: 100%;
padding: 12px 14px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
text-align: left;
transition: border-color 120ms ease, background 120ms ease;
}
.toggle-row:hover { border-color: var(--border-strong); }
.toggle-row.on { border-color: var(--accent); background: var(--accent-tint); }
.toggle-row-text {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.toggle-row-label {
font-size: 13px;
font-weight: 500;
color: var(--text);
}
.toggle-row-hint {
font-size: 11.5px;
color: var(--text-muted);
line-height: 1.4;
}
.toggle-row-switch {
flex: none;
position: relative;
width: 32px;
height: 18px;
border-radius: 999px;
background: var(--border-strong);
transition: background 160ms ease;
}
.toggle-row-switch::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 14px;
height: 14px;
border-radius: 50%;
background: #fff;
box-shadow: 0 1px 2px rgba(28, 27, 26, 0.18);
transition: transform 160ms cubic-bezier(0.2, 0, 0.2, 1);
}
.toggle-row.on .toggle-row-switch { background: var(--accent); }
.toggle-row.on .toggle-row-switch::after { transform: translateX(14px); }
/* -------- Template picker (template tab) ---------------------------- */
.template-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.template-option {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 12px 14px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
text-align: left;
transition: border-color 120ms ease, background 120ms ease;
}
.template-option:hover { border-color: var(--border-strong); }
.template-option.active {
border-color: var(--accent);
background: var(--accent-tint);
}
.template-radio {
flex: none;
margin-top: 2px;
width: 14px;
height: 14px;
border-radius: 50%;
border: 1.5px solid var(--border-strong);
background: var(--bg-panel);
position: relative;
}
.template-radio.active {
border-color: var(--accent);
background: var(--bg-panel);
}
.template-radio.active::after {
content: '';
position: absolute;
inset: 2px;
border-radius: 50%;
background: var(--accent);
}
.template-option-text {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.template-option-name {
font-size: 13px;
font-weight: 500;
color: var(--text);
}
.template-option-desc {
font-size: 11.5px;
color: var(--text-muted);
line-height: 1.4;
}
.template-howto {
display: flex;
flex-direction: column;
gap: 4px;
padding: 12px 14px;
background: var(--bg-subtle);
border: 1px dashed var(--border-strong);
border-radius: var(--radius-sm);
}
.template-howto-title {
font-size: 12.5px;
font-weight: 500;
color: var(--text);
}
.template-howto-body {
font-size: 11.5px;
color: var(--text-muted);
line-height: 1.45;
}
/* -------- New project · connectors section (live-artifact tab) ----- */
.newproj-connectors { gap: 8px; }
.newproj-connectors-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.newproj-connectors-manage {
padding: 2px 8px;
font-size: 11px;
font-weight: 500;
letter-spacing: 0.02em;
color: var(--text-muted);
background: transparent;
border: 1px solid var(--border);
border-radius: 999px;
cursor: pointer;
transition: color 120ms ease, border-color 120ms ease, background 120ms ease;
}
.newproj-connectors-manage:hover {
color: var(--text);
border-color: var(--border-strong);
background: var(--bg-subtle);
}
.newproj-connectors-hint {
font-size: 11.5px;
color: var(--text-muted);
line-height: 1.45;
}
.newproj-connectors-list {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.newproj-connector-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px 4px 8px;
font-size: 11.5px;
color: var(--text);
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: 999px;
max-width: 100%;
min-width: 0;
}
.newproj-connector-dot {
width: 6px;
height: 6px;
border-radius: 999px;
background: #3bb273;
box-shadow: 0 0 0 3px color-mix(in srgb, #3bb273 22%, transparent);
flex: none;
}
.newproj-connector-name {
font-weight: 500;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 140px;
}
.newproj-connector-account {
color: var(--text-muted);
font-size: 11px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: 120px;
}
.newproj-connectors-empty {
display: flex;
align-items: flex-start;
gap: 10px;
width: 100%;
padding: 12px 14px;
background: var(--bg-subtle);
border: 1px dashed var(--border-strong);
border-radius: var(--radius-sm);
cursor: pointer;
text-align: left;
transition: border-color 140ms ease, background 140ms ease, transform 140ms ease;
}
.newproj-connectors-empty:hover {
border-color: var(--accent);
border-style: solid;
background: color-mix(in srgb, var(--accent) 4%, var(--bg-subtle));
}
.newproj-connectors-empty:active { transform: translateY(1px); }
.newproj-connectors-empty:focus-visible {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 30%, transparent);
}
.newproj-connectors-empty-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 26px;
height: 26px;
flex: none;
border-radius: 8px;
background: var(--bg-panel);
border: 1px solid var(--border);
color: var(--text-muted);
}
.newproj-connectors-empty:hover .newproj-connectors-empty-icon {
color: var(--accent);
border-color: color-mix(in srgb, var(--accent) 40%, var(--border));
}
.newproj-connectors-empty-text {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.newproj-connectors-empty-title {
font-size: 12.5px;
font-weight: 500;
color: var(--text);
}
.newproj-connectors-empty-body {
font-size: 11.5px;
color: var(--text-muted);
line-height: 1.45;
}
.newproj-connectors-empty-cta {
margin-top: 4px;
font-size: 11.5px;
font-weight: 500;
color: var(--accent);
}
/* -------- Design system picker (custom popover dropdown) ------------ */
.ds-picker { position: relative; }
.ds-picker-trigger {
display: flex;
align-items: center;
gap: 10px;
width: 100%;
padding: 8px 10px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
text-align: left;
transition: border-color 120ms ease, box-shadow 120ms ease;
}
.ds-picker-trigger:hover { border-color: var(--border-strong); }
.ds-picker-trigger.open {
border-color: var(--accent);
box-shadow: 0 0 0 1px var(--accent);
}
.ds-picker-meta {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 1px;
}
.ds-picker-title {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 13px;
font-weight: 500;
color: var(--text);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ds-picker-extra-pill {
font-size: 10px;
font-weight: 600;
letter-spacing: 0.04em;
padding: 1px 6px;
background: var(--accent-soft);
color: var(--accent);
border-radius: 999px;
}
.ds-picker-sub {
font-size: 11px;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ds-picker-chevron {
flex: none;
color: var(--text-muted);
transition: transform 160ms ease;
}
.ds-picker-trigger.empty .ds-picker-title { color: var(--text-muted); font-weight: 500; }
/* Avatar — square with 2x2 swatch grid (or "none" diagonal slash). */
.ds-avatar {
position: relative;
flex: none;
width: 32px;
height: 32px;
border-radius: 6px;
overflow: hidden;
border: 1px solid var(--border);
background: var(--bg-panel);
display: inline-flex;
align-items: center;
justify-content: center;
}
.ds-avatar-grid {
display: grid;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
width: 100%;
height: 100%;
}
.ds-avatar-cell { display: block; }
.ds-avatar-stack {
position: absolute;
right: -2px;
bottom: -2px;
font-size: 9px;
font-weight: 600;
letter-spacing: 0.02em;
padding: 1px 5px;
background: var(--text-strong);
color: #fff;
border-radius: 999px;
border: 2px solid var(--bg-panel);
}
.ds-avatar-none {
background: var(--bg-subtle);
color: var(--text-faint);
}
/* Popover */
.ds-picker-popover {
position: absolute;
top: calc(100% + 6px);
left: 0;
right: 0;
z-index: 30;
display: flex;
flex-direction: column;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-lg);
overflow: hidden;
animation: ds-pop-in 140ms cubic-bezier(0.2, 0, 0.2, 1);
}
@keyframes ds-pop-in {
from { opacity: 0; transform: translateY(-4px); }
to { opacity: 1; transform: translateY(0); }
}
.ds-picker-head {
display: flex;
align-items: center;
gap: 8px;
padding: 8px;
border-bottom: 1px solid var(--border);
background: var(--bg-subtle);
}
.ds-picker-search {
flex: 1;
padding: 6px 10px !important;
font-size: 12.5px;
background: var(--bg-panel);
border: 1px solid var(--border) !important;
border-radius: var(--radius-sm) !important;
}
.ds-picker-mode {
flex: none;
display: inline-flex;
padding: 2px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: 999px;
}
.ds-picker-mode-btn {
padding: 3px 10px !important;
font-size: 11px !important;
font-weight: 500;
border: none !important;
background: transparent !important;
color: var(--text-muted) !important;
border-radius: 999px !important;
box-shadow: none !important;
}
.ds-picker-mode-btn.active {
background: var(--accent) !important;
color: #fff !important;
}
.ds-picker-list {
display: flex;
flex-direction: column;
max-height: 320px;
overflow-y: auto;
padding: 4px;
}
.ds-picker-empty {
padding: 16px 12px;
font-size: 12px;
color: var(--text-muted);
text-align: center;
}
.ds-picker-item {
display: flex;
align-items: center;
gap: 10px;
padding: 8px;
background: transparent;
border: 1px solid transparent;
border-radius: var(--radius-sm);
cursor: pointer;
text-align: left;
}
.ds-picker-item:hover { background: var(--bg-subtle); }
.ds-picker-item.active {
background: var(--accent-tint);
border-color: var(--accent-soft);
}
.ds-picker-item-text {
flex: 1;
min-width: 0;
display: flex;
flex-direction: column;
gap: 1px;
}
.ds-picker-item-title {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 12.5px;
font-weight: 500;
color: var(--text);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.ds-picker-item-badge {
font-size: 9px;
font-weight: 600;
letter-spacing: 0.06em;
padding: 2px 5px;
background: var(--accent-soft);
color: var(--accent);
border-radius: 4px;
}
.ds-picker-item-sub {
font-size: 11px;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Selection mark — a circle for single-select, a square for multi.
In multi mode the active state shows the pick order (1 = primary). */
.ds-picker-mark {
flex: none;
display: inline-flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
font-size: 10px;
font-weight: 600;
color: transparent;
}
.ds-picker-mark.radio {
border-radius: 50%;
border: 1.5px solid var(--border-strong);
background: var(--bg-panel);
position: relative;
}
.ds-picker-mark.radio.active {
border-color: var(--accent);
}
.ds-picker-mark.radio.active::after {
content: '';
width: 9px;
height: 9px;
border-radius: 50%;
background: var(--accent);
}
.ds-picker-mark.check {
border-radius: 4px;
border: 1.5px solid var(--border-strong);
background: var(--bg-panel);
color: var(--bg-panel);
}
.ds-picker-mark.check.active {
border-color: var(--accent);
background: var(--accent);
color: #fff;
}
.ds-picker-foot {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 10px;
border-top: 1px solid var(--border);
background: var(--bg-subtle);
font-size: 11.5px;
color: var(--text-muted);
line-height: 1.4;
}
.ds-picker-foot-text { flex: 1; min-width: 0; }
.ds-picker-foot-text strong { color: var(--text); font-weight: 600; }
.ds-picker-clear {
flex: none;
padding: 4px 10px !important;
font-size: 11px !important;
background: var(--bg-panel) !important;
color: var(--text) !important;
border: 1px solid var(--border) !important;
}
.ds-picker-clear:hover { border-color: var(--border-strong) !important; }
.entry-side-foot {
margin-top: auto;
display: flex;
flex-direction: column;
gap: 6px;
padding-top: 16px;
}
.entry-side-foot .foot-pill {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-pill);
font-size: 11.5px;
color: var(--text-muted);
align-self: flex-start;
cursor: pointer;
text-decoration: none;
}
.entry-side-foot .foot-pill:hover { background: var(--bg-panel); border-color: var(--border-strong); color: var(--text); }
.entry-side-foot .foot-pill .ico { font-size: 12px; opacity: 0.7; }
/* Language switcher pill + popover (entry sidebar foot). */
.lang-menu-wrap {
position: relative;
align-self: flex-start;
}
.lang-menu-wrap .lang-pill {
font-variant-numeric: tabular-nums;
}
.lang-menu-popover {
position: absolute;
bottom: calc(100% + 6px);
left: 0;
z-index: 50;
min-width: 180px;
width: max-content;
max-width: min(280px, calc(100vw - 48px));
display: flex;
flex-direction: column;
padding: 4px;
background: var(--bg-panel);
border: 1px solid var(--border-strong);
border-radius: 10px;
box-shadow: 0 12px 28px rgba(0, 0, 0, 0.12);
}
.lang-menu-item {
display: grid;
grid-template-columns: minmax(0, 1fr) auto auto;
align-items: center;
gap: 10px;
padding: 7px 10px;
background: transparent;
border: 0;
border-radius: 7px;
font-size: 12.5px;
color: var(--text);
text-align: left;
cursor: pointer;
}
.lang-menu-label {
min-width: 0;
overflow-wrap: anywhere;
}
.lang-menu-item:hover { background: var(--bg-subtle); }
.lang-menu-item.active { background: var(--bg-subtle); }
.lang-menu-item .lang-menu-code {
color: var(--text-faint);
font-size: 11px;
font-variant-numeric: tabular-nums;
letter-spacing: 0.02em;
}
.lang-menu-item .lang-menu-check {
color: var(--text-muted);
display: inline-flex;
align-items: center;
}
/* Right side */
.entry-main {
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
}
.entry-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 0 28px;
border-bottom: 1px solid var(--border);
min-width: 0;
min-height: 52px;
}
.entry-header-tabs-row {
display: flex;
align-items: center;
gap: 24px;
}
.entry-tabs {
display: flex;
gap: 2px;
min-width: 0;
overflow-x: auto;
overflow-y: hidden;
scrollbar-width: none;
}
.entry-tabs::-webkit-scrollbar { display: none; }
.entry-tab {
background: transparent;
border: none;
border-bottom: 2px solid transparent;
border-radius: 6px 6px 0 0;
padding: 14px 11px;
font-size: 14px;
color: var(--text-muted);
font-weight: 500;
flex: 0 0 auto;
white-space: nowrap;
}
.entry-tab:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); }
.entry-tab.active {
color: var(--text);
border-bottom-color: var(--text);
}
.entry-header-right {
display: inline-flex;
align-items: center;
gap: 8px;
flex: 0 0 auto;
}
.entry-tab-content {
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 22px 28px 32px;
background: var(--bg);
}
.tab-panel {
display: flex;
flex-direction: column;
gap: 18px;
}
.tab-panel-toolbar {
display: flex;
gap: 10px;
align-items: center;
justify-content: space-between;
flex-wrap: wrap;
/* Older browsers ignore row-gap on flex with wrap — explicit row-gap keeps
the wrapped row visually separated rather than flush against the pill. */
row-gap: 8px;
}
.tab-panel-toolbar .toolbar-left {
display: flex;
gap: 8px;
align-items: center;
flex: 0 0 auto;
min-width: 0;
}
.tab-panel-toolbar .toolbar-right {
display: flex;
gap: 8px;
align-items: center;
flex: 1 1 auto;
min-width: 0;
justify-content: flex-end;
flex-wrap: wrap;
}
.tab-panel-toolbar .toolbar-search {
position: relative;
flex: 1 1 180px;
min-width: 140px;
max-width: 280px;
}
/* Narrow columns (entry tab content sometimes lands at ~570px wide) — keep
the segmented pill on its own row above the search/view toggle so the
search input never collapses into a tiny stub squeezed between two pills. */
@media (max-width: 720px) {
.tab-panel-toolbar { flex-direction: column; align-items: stretch; }
.tab-panel-toolbar .toolbar-left { justify-content: flex-start; }
.tab-panel-toolbar .toolbar-right { justify-content: space-between; }
.tab-panel-toolbar .toolbar-search { max-width: none; }
}
.tab-panel-toolbar .toolbar-search input {
padding-left: 30px;
background: var(--bg-panel);
}
.tab-panel-toolbar .toolbar-search input[type='search']::-webkit-search-cancel-button {
/* Hide the native clear control; we render our own styled button. */
appearance: none;
-webkit-appearance: none;
}
.tab-panel-toolbar .toolbar-search input[disabled] {
opacity: 0.6;
cursor: not-allowed;
}
.tab-panel-toolbar .toolbar-search .toolbar-search-clear {
position: absolute;
right: 6px;
top: 50%;
transform: translateY(-50%);
display: inline-flex;
align-items: center;
justify-content: center;
width: 20px;
height: 20px;
padding: 0;
border: 0;
border-radius: 999px;
background: transparent;
color: var(--text-faint);
cursor: pointer;
transition: background-color 120ms ease, color 120ms ease;
}
.tab-panel-toolbar .toolbar-search .toolbar-search-clear:hover {
background: var(--bg-subtle);
color: var(--text);
}
.tab-panel-toolbar .toolbar-search .toolbar-search-clear:focus-visible {
outline: 2px solid var(--text);
outline-offset: 2px;
}
.tab-panel-toolbar .toolbar-search .search-icon {
position: absolute;
left: 9px;
top: 50%;
transform: translateY(-50%);
color: var(--text-faint);
font-size: 13px;
pointer-events: none;
}
.tab-empty {
padding: 48px 0;
text-align: center;
color: var(--text-muted);
font-size: 13px;
}
.connectors-heading h2 {
margin: 0;
font-size: 18px;
line-height: 1.25;
}
.connectors-heading p {
margin: 4px 0 0;
color: var(--text-muted);
font-size: 13px;
}
.tab-panel-toolbar .toolbar-search.connectors-search {
flex: 0 1 320px;
width: min(320px, 100%);
}
.tab-panel-toolbar .toolbar-search.connectors-search input {
padding-right: 32px;
}
.connectors-empty {
display: flex;
flex-direction: column;
align-items: center;
gap: 8px;
padding: 64px 16px;
text-align: center;
}
.connectors-empty-title {
margin: 0;
font-size: 14px;
color: var(--text);
font-weight: 500;
max-width: 480px;
word-break: break-word;
}
.connectors-empty-body {
margin: 0;
font-size: 13px;
color: var(--text-muted);
max-width: 480px;
}
.connectors-empty-action {
margin-top: 8px;
}
.connector-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(268px, 1fr));
gap: 14px;
}
.connector-card {
position: relative;
display: flex;
flex-direction: column;
gap: 12px;
min-height: 168px;
padding: 16px 16px 14px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-xs);
cursor: pointer;
text-align: left;
transition:
transform 140ms ease,
border-color 140ms ease,
box-shadow 180ms ease,
background 140ms ease;
}
.connector-card:hover:not(.is-locked) {
transform: translateY(-1px);
border-color: color-mix(in srgb, var(--text) 28%, var(--border));
box-shadow: 0 8px 24px -14px rgba(0, 0, 0, 0.25), var(--shadow-xs);
}
.connector-card:focus-visible {
outline: none;
border-color: color-mix(in srgb, var(--text) 48%, var(--border));
box-shadow:
0 0 0 3px color-mix(in srgb, var(--text) 14%, transparent),
0 8px 24px -14px rgba(0, 0, 0, 0.25);
}
.connector-card.status-connected {
border-color: color-mix(in srgb, var(--green) 40%, var(--border));
background: linear-gradient(
180deg,
color-mix(in srgb, var(--green) 5%, var(--bg-panel)) 0%,
var(--bg-panel) 60%
);
}
.connector-card.status-disabled { background: var(--bg-subtle); }
.connector-card.status-error {
border-color: color-mix(in srgb, var(--red) 35%, var(--border));
}
.connector-card-top {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
}
.connector-card-head {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
flex: 1 1 auto;
}
.connector-card-title {
margin: 0;
font-size: 15px;
font-weight: 600;
line-height: 1.25;
letter-spacing: -0.005em;
color: var(--text);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.connector-meta {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 6px;
color: var(--text-muted);
font-size: 12px;
line-height: 1;
}
.connector-meta-item {
white-space: nowrap;
}
.connector-meta-dot {
color: var(--text-faint);
}
.connector-tools-badge {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 7px;
border-radius: var(--radius-pill);
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
font-size: 11px;
font-weight: 500;
line-height: 1.3;
white-space: nowrap;
transform-origin: left center;
will-change: transform, opacity;
}
.connector-tools-badge svg {
opacity: 0.65;
}
.connector-tools-badge.is-ready {
animation: connector-tools-badge-in 420ms cubic-bezier(0.22, 1, 0.36, 1) both;
}
.connector-tools-badge.is-ready svg {
animation: connector-tools-badge-icon-in 520ms cubic-bezier(0.22, 1, 0.36, 1) both;
animation-delay: 120ms;
}
@keyframes connector-tools-badge-in {
0% {
opacity: 0;
transform: translateY(3px) scale(0.92);
border-color: color-mix(in srgb, var(--border) 40%, transparent);
background: color-mix(in srgb, var(--bg-subtle) 60%, transparent);
}
55% {
opacity: 1;
border-color: color-mix(in srgb, var(--accent, var(--text-muted)) 30%, var(--border));
}
100% {
opacity: 1;
transform: translateY(0) scale(1);
border-color: var(--border);
background: var(--bg-subtle);
}
}
@keyframes connector-tools-badge-icon-in {
0% {
opacity: 0;
transform: rotate(-12deg) scale(0.8);
}
100% {
opacity: 0.65;
transform: rotate(0) scale(1);
}
}
@media (prefers-reduced-motion: reduce) {
.connector-tools-badge.is-ready {
animation: connector-tools-badge-fade 180ms ease-out both;
}
.connector-tools-badge.is-ready svg {
animation: none;
}
@keyframes connector-tools-badge-fade {
from { opacity: 0; }
to { opacity: 1; }
}
}
.connector-status {
flex: 0 0 auto;
display: inline-flex;
align-items: center;
gap: 5px;
padding: 2px 8px;
border-radius: var(--radius-pill);
background: var(--bg-subtle);
color: var(--text-muted);
border: 1px solid var(--border);
font-size: 11px;
font-weight: 600;
line-height: 1.4;
letter-spacing: 0.01em;
}
.connector-status-dot {
width: 6px;
height: 6px;
border-radius: 999px;
background: currentColor;
box-shadow: 0 0 0 2px color-mix(in srgb, currentColor 22%, transparent);
}
.connector-status.status-connected,
.connector-status-pill.status-connected {
background: color-mix(in srgb, var(--green) 12%, transparent);
color: var(--green);
border-color: color-mix(in srgb, var(--green) 32%, transparent);
}
.connector-status.status-error,
.connector-status-pill.status-error {
background: color-mix(in srgb, var(--red) 10%, transparent);
color: var(--red);
border-color: color-mix(in srgb, var(--red) 30%, transparent);
}
.connector-status.status-disabled,
.connector-status-pill.status-disabled {
opacity: 0.7;
}
.connector-status-pill {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 3px 10px;
border-radius: var(--radius-pill);
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
font-size: 12px;
font-weight: 600;
}
.connector-description {
margin: 0;
color: var(--text-muted);
font-size: 13px;
line-height: 1.5;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.connector-actions {
display: flex;
align-items: center;
gap: 8px;
margin-top: auto;
padding-top: 4px;
}
button.connector-action {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 5px 12px;
font-size: 12px;
font-weight: 500;
border-radius: var(--radius);
transition: transform 120ms ease, background 140ms ease, border-color 140ms ease;
}
button.connector-action.is-connect {
min-width: 92px;
}
button.connector-action.is-disconnect {
min-width: 106px;
color: var(--text-muted);
}
button.connector-action.is-disconnect:hover:not(:disabled) {
color: var(--red);
border-color: color-mix(in srgb, var(--red) 35%, var(--border));
}
button.connector-action.is-loading {
cursor: wait;
}
/* Connector gate — masks the grid when the Composio API key is missing. */
.connector-grid-wrap {
position: relative;
}
.connector-grid-wrap.is-masked .connector-grid {
filter: blur(2px) saturate(0.85);
opacity: 0.55;
pointer-events: none;
user-select: none;
transition: filter 160ms ease, opacity 160ms ease;
}
/* When the gate is shown, anchor it to the visible first screen of the
connectors tab instead of centering across the full (potentially long)
connector list. We lift the tab-content into a flex column, let the
connectors panel and the masked grid wrap stretch to fill the remaining
viewport height, and hide overflow so the absolutely-positioned gate
card remains fixed in the first-screen center. */
.entry-tab-content:has(> .tab-panel.connectors-panel > .connector-grid-wrap.is-masked) {
display: flex;
flex-direction: column;
overflow: hidden;
}
.tab-panel.connectors-panel:has(> .connector-grid-wrap.is-masked) {
flex: 1 1 auto;
min-height: 0;
}
.connector-grid-wrap.is-masked {
flex: 1 1 auto;
min-height: 0;
overflow: hidden;
}
.connector-grid-wrap.is-masked .connector-grid {
/* Prevent the blurred grid from introducing its own scroll height inside
the now-clipped wrap — the wrap is our visible viewport for the gate. */
max-height: 100%;
overflow: hidden;
}
.connector-card.is-locked {
cursor: not-allowed;
}
.connector-gate {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
background:
radial-gradient(ellipse at top, color-mix(in srgb, var(--bg-panel) 78%, transparent) 0%, color-mix(in srgb, var(--bg) 72%, transparent) 65%),
color-mix(in srgb, var(--bg) 45%, transparent);
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
border-radius: var(--radius);
animation: connector-gate-fade 220ms ease-out;
}
@keyframes connector-gate-fade {
from { opacity: 0; transform: translateY(4px); }
to { opacity: 1; transform: translateY(0); }
}
.connector-gate-card {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
max-width: 420px;
padding: 28px 28px 24px;
text-align: center;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-md, 0 10px 30px rgba(0, 0, 0, 0.18));
}
.connector-gate-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 40px;
height: 40px;
border-radius: 50%;
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
}
.connector-gate-title {
margin: 2px 0 0;
font-size: 15px;
font-weight: 600;
color: var(--text);
letter-spacing: 0.01em;
}
.connector-gate-body {
margin: 0;
max-width: 340px;
color: var(--text-muted);
font-size: 13px;
line-height: 1.5;
}
.connector-gate-action {
margin-top: 6px;
padding: 7px 16px;
font-size: 13px;
font-weight: 500;
}
/* ------------------------------------------------------------------ */
/* Connector detail drawer */
/* ------------------------------------------------------------------ */
.connector-drawer-backdrop {
position: fixed;
inset: 0;
z-index: 100;
background: color-mix(in srgb, #000 42%, transparent);
backdrop-filter: blur(2px);
-webkit-backdrop-filter: blur(2px);
display: flex;
justify-content: flex-end;
animation: connector-drawer-fade 180ms ease;
}
@keyframes connector-drawer-fade {
from { opacity: 0; }
to { opacity: 1; }
}
.connector-drawer {
position: relative;
display: flex;
flex-direction: column;
width: min(480px, 92vw);
height: 100%;
background: var(--bg-panel);
border-left: 1px solid var(--border);
box-shadow: -24px 0 48px -20px rgba(0, 0, 0, 0.32);
animation: connector-drawer-slide 240ms cubic-bezier(0.22, 0.9, 0.3, 1);
}
@keyframes connector-drawer-slide {
from { transform: translateX(24px); opacity: 0; }
to { transform: translateX(0); opacity: 1; }
}
.connector-drawer-head {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 20px 22px 16px;
border-bottom: 1px solid var(--border);
background:
linear-gradient(180deg, color-mix(in srgb, var(--bg-subtle) 60%, transparent) 0%, transparent 100%);
}
.connector-drawer-titles {
flex: 1 1 auto;
min-width: 0;
display: flex;
flex-direction: column;
gap: 8px;
}
.connector-drawer-eyebrow {
display: flex;
align-items: center;
gap: 6px;
font-size: 11px;
font-weight: 500;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--text-faint);
}
.connector-drawer-titles h2 {
margin: 0;
font-size: 22px;
font-weight: 600;
line-height: 1.2;
letter-spacing: -0.01em;
color: var(--text);
}
.connector-drawer-status {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.connector-drawer-close {
flex: 0 0 auto;
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
border-radius: 999px;
color: var(--text-muted);
}
.connector-drawer-close:hover {
background: var(--bg-subtle);
color: var(--text);
}
.connector-drawer-body {
flex: 1 1 auto;
overflow-y: auto;
padding: 20px 22px 24px;
display: flex;
flex-direction: column;
gap: 22px;
}
.connector-drawer-section {
display: flex;
flex-direction: column;
gap: 10px;
}
.connector-drawer-section-title {
margin: 0;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text-faint);
display: flex;
align-items: center;
gap: 8px;
}
.connector-drawer-count {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 20px;
height: 18px;
padding: 0 6px;
border-radius: 999px;
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
font-size: 10px;
font-weight: 600;
letter-spacing: 0;
text-transform: none;
}
.connector-drawer-description {
margin: 0;
color: var(--text);
font-size: 14px;
line-height: 1.6;
}
.connector-drawer-details {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: 2px;
margin: 0;
padding: 2px 0;
border-radius: var(--radius);
border: 1px solid var(--border);
background: var(--bg-subtle);
overflow: hidden;
}
.connector-drawer-details > div {
display: grid;
grid-template-columns: 110px 1fr;
align-items: baseline;
gap: 12px;
padding: 10px 14px;
background: var(--bg-panel);
}
.connector-drawer-details > div + div {
border-top: 1px solid var(--border);
}
.connector-drawer-details dt {
margin: 0;
color: var(--text-muted);
font-size: 12px;
font-weight: 500;
}
.connector-drawer-details dd {
margin: 0;
color: var(--text);
font-size: 13px;
word-break: break-word;
}
.connector-drawer-details-error dd {
color: var(--red);
}
.connector-drawer-empty {
margin: 0;
padding: 14px 16px;
border: 1px dashed var(--border);
border-radius: var(--radius);
color: var(--text-muted);
font-size: 13px;
line-height: 1.5;
}
.connector-drawer-tools {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 8px;
}
.connector-drawer-tool {
display: flex;
flex-direction: column;
gap: 6px;
padding: 12px 14px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
transition: border-color 140ms ease, background 140ms ease;
}
.connector-drawer-tool:hover {
border-color: color-mix(in srgb, var(--text) 20%, var(--border));
}
.connector-drawer-tool-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.connector-drawer-tool-title {
font-size: 13px;
font-weight: 600;
color: var(--text);
}
.connector-drawer-tool-badge {
display: inline-flex;
align-items: center;
padding: 1px 7px;
border-radius: var(--radius-pill);
font-size: 10px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.06em;
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
}
.connector-drawer-tool-badge.side-read {
background: color-mix(in srgb, var(--green) 10%, transparent);
border-color: color-mix(in srgb, var(--green) 28%, transparent);
color: var(--green);
}
.connector-drawer-tool-badge.side-write {
background: color-mix(in srgb, var(--amber, #d97706) 10%, transparent);
border-color: color-mix(in srgb, var(--amber, #d97706) 28%, transparent);
color: var(--amber, #d97706);
}
.connector-drawer-tool-badge.side-destructive {
background: color-mix(in srgb, var(--red) 10%, transparent);
border-color: color-mix(in srgb, var(--red) 30%, transparent);
color: var(--red);
}
.connector-drawer-tool-desc {
margin: 0;
color: var(--text-muted);
font-size: 12.5px;
line-height: 1.5;
}
.connector-drawer-tool-name {
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
font-size: 11px;
color: var(--text-faint);
background: var(--bg-subtle);
padding: 2px 6px;
border-radius: 4px;
align-self: flex-start;
max-width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.connector-drawer-foot {
padding: 14px 22px 18px;
border-top: 1px solid var(--border);
display: flex;
justify-content: flex-end;
gap: 8px;
background: var(--bg-panel);
}
.connector-drawer-foot button.connector-action {
padding: 7px 18px;
font-size: 13px;
}
@media (max-width: 520px) {
.connector-drawer-head {
padding: 16px 16px 14px;
}
.connector-drawer-body {
padding: 16px 16px 20px;
}
.connector-drawer-foot {
padding: 12px 16px 16px;
}
.connector-drawer-details > div {
grid-template-columns: 1fr;
gap: 2px;
}
}
/* Recent / Your designs segmented pill */
.subtab-pill {
display: inline-flex;
padding: 3px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-pill);
gap: 2px;
max-width: 100%;
overflow-x: auto;
scrollbar-width: none;
}
.subtab-pill::-webkit-scrollbar { display: none; }
.subtab-pill button {
background: transparent;
border: none;
border-radius: var(--radius-pill);
padding: 5px 16px;
font-size: 12px;
color: var(--text-muted);
font-weight: 500;
white-space: nowrap;
}
.subtab-pill button:hover:not(.active) { background: rgba(255,255,255,0.6); border-color: transparent; color: var(--text); }
.subtab-pill button.active {
background: var(--text);
color: var(--bg);
box-shadow: var(--shadow-xs);
}
/* Icon-only variant: any pill button whose sole child is an SVG icon.
Center the glyph via inline-flex (removes text line-height drift) and
use padding that matches the text variant's overall height so both
sub-pills align on the same baseline in the toolbar. */
.subtab-pill button:has(> svg:only-child) {
padding: 5px 8px;
display: inline-flex;
align-items: center;
justify-content: center;
line-height: 0;
}
/* Designs grid */
.design-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
gap: 14px;
}
.design-card {
position: relative;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 0;
cursor: pointer;
transition: border-color 120ms ease, box-shadow 120ms ease, transform 120ms ease;
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 168px;
}
.design-card:hover { border-color: var(--border-strong); box-shadow: var(--shadow-sm); transform: translateY(-1px); }
.design-card-thumb {
flex: 1;
min-height: 100px;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-subtle);
color: var(--text-faint);
font-size: 38px;
position: relative;
}
.design-card-thumb::before {
/* Folder-shape icon */
content: '';
width: 56px;
height: 44px;
background: var(--bg-panel);
border: 1px solid var(--border-strong);
border-radius: 4px 6px 6px 6px;
position: relative;
box-shadow: var(--shadow-xs);
}
.design-card-thumb::after {
/* Folder tab notch */
content: '';
position: absolute;
width: 22px;
height: 8px;
background: var(--bg-panel);
border: 1px solid var(--border-strong);
border-bottom: none;
border-radius: 4px 4px 0 0;
margin-top: -52px;
margin-left: -26px;
}
.design-card-meta-block {
padding: 10px 12px 12px;
display: flex;
flex-direction: column;
gap: 2px;
border-top: 1px solid var(--border-soft);
background: var(--bg-panel);
}
.design-card-name {
font-weight: 600;
font-size: 13px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
color: var(--text-strong);
}
.design-card-meta {
font-size: 11.5px;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.design-card-meta .ds {
color: var(--accent);
}
.design-card-status {
font-weight: 500;
}
.design-card-status-running {
color: var(--accent);
}
.design-card-status-awaiting_input {
color: var(--amber);
}
.design-card-status-queued,
.design-card-status-not_started,
.design-card-status-canceled {
color: var(--text-muted);
}
.design-card-status-succeeded {
color: var(--green);
}
.design-card-status-failed {
color: var(--red);
}
.design-card-close {
position: absolute;
top: 8px;
right: 8px;
width: 22px;
height: 22px;
padding: 0;
border-radius: 50%;
font-size: 14px;
line-height: 1;
background: var(--bg-panel);
opacity: 0;
transition: opacity 0.15s;
border-color: var(--border);
z-index: 2;
/* Keep button interactive for keyboard/AT users even while visually hidden. */
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
}
.design-card:hover .design-card-close,
.design-card:focus-within .design-card-close,
.design-kanban-card:hover .design-card-close,
.design-kanban-card:focus-within .design-card-close,
.design-card-close:focus-visible { opacity: 1; }
.design-card-close:hover { color: var(--text-strong); border-color: var(--border-strong); }
/* Larger comfortable touch target on coarse pointers (tablets/touch laptops).
On touch the hover reveal never fires, so keep the close button visible. */
@media (hover: none) {
.design-card .design-card-close,
.design-kanban-card .design-card-close { opacity: 1; }
}
/* Featured (tutorial) card variant */
.design-card.featured .design-card-thumb {
background: linear-gradient(180deg, #e8efff 0%, #d8e3ff 100%);
}
.design-card.featured .design-card-thumb::before {
background: var(--bg-panel);
border-color: rgba(35, 72, 184, 0.18);
}
.design-card.featured .design-card-thumb::after { display: none; }
.live-artifact-card {
border-color: color-mix(in srgb, var(--accent) 28%, var(--border));
}
.live-artifact-card:hover {
border-color: color-mix(in srgb, var(--accent) 48%, var(--border-strong));
}
.live-artifact-thumb {
background:
radial-gradient(circle at 32% 28%, rgba(116, 92, 255, 0.18), transparent 36%),
linear-gradient(135deg, rgba(66, 153, 225, 0.16), rgba(116, 92, 255, 0.12));
}
.live-artifact-thumb::before,
.live-artifact-thumb::after {
display: none;
}
.live-artifact-thumb-glyph {
width: 46px;
height: 46px;
border-radius: 16px;
display: grid;
place-items: center;
color: var(--accent);
background: var(--bg-panel);
border: 1px solid color-mix(in srgb, var(--accent) 24%, var(--border));
box-shadow: var(--shadow-xs);
font-size: 18px;
line-height: 1;
}
.design-card-badges,
.live-artifact-badges {
display: flex;
flex-wrap: wrap;
gap: 5px;
min-height: 18px;
}
.live-artifact-badge,
.design-live-count {
display: inline-flex;
align-items: center;
border-radius: 999px;
border: 1px solid var(--border);
padding: 2px 7px;
font-size: 10px;
font-weight: 700;
letter-spacing: 0.03em;
text-transform: uppercase;
background: var(--bg-panel);
}
.live-artifact-badge.live {
color: var(--accent);
border-color: color-mix(in srgb, var(--accent) 32%, var(--border));
background: color-mix(in srgb, var(--accent) 9%, var(--bg-panel));
}
.live-artifact-badge.refreshing {
color: #1d4ed8;
border-color: rgba(29, 78, 216, 0.22);
background: rgba(29, 78, 216, 0.08);
}
.live-artifact-badge.refresh-failed {
color: #b42318;
border-color: rgba(180, 35, 24, 0.22);
background: rgba(180, 35, 24, 0.08);
}
.live-artifact-badge.archived {
color: var(--text-muted);
border-color: var(--border-strong);
background: var(--bg-subtle);
}
.live-artifact-badges.compact {
display: inline-flex;
gap: 4px;
min-height: 0;
vertical-align: middle;
}
.live-artifact-badges.compact .live-artifact-badge {
padding: 1px 5px;
font-size: 9px;
line-height: 1.25;
}
.design-live-count {
position: absolute;
right: 10px;
bottom: 10px;
color: var(--accent);
border-color: color-mix(in srgb, var(--accent) 26%, var(--border));
box-shadow: var(--shadow-xs);
}
/* Grid card keyboard focus (cards carry role="button" on a div). */
.design-card:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-color: var(--border-strong);
}
/* Kanban View */
.tab-panel.design-kanban-view {
/* Fill the scrollable parent (.entry-tab-content) so columns can size to
the available viewport without a fragile 100vh calc. */
flex: 1 1 auto;
min-height: 0;
height: 100%;
}
.design-kanban-board {
display: flex;
gap: 14px;
overflow-x: auto;
/* Let columns grow to fill the remaining vertical space inside
.tab-panel.design-kanban-view. */
flex: 1 1 auto;
min-height: 0;
padding-bottom: 8px;
/* Hint that horizontal content may overflow on narrow viewports. */
scroll-snap-type: x proximity;
scrollbar-gutter: stable;
}
.design-kanban-col {
width: 280px;
flex-shrink: 0;
display: flex;
flex-direction: column;
background: var(--bg-subtle);
border-radius: var(--radius);
padding: 12px;
gap: 12px;
min-height: 0;
scroll-snap-align: start;
}
.design-kanban-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
font-size: 13px;
font-weight: 500;
color: var(--text-strong);
padding-left: 2px;
/* Prevent long status labels from pushing the count chip out of the column. */
min-width: 0;
}
.design-kanban-header > span:first-child {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.design-kanban-count {
background: var(--bg-panel);
border: 1px solid var(--border-soft);
color: var(--text-muted);
font-size: 11px;
padding: 2px 8px;
border-radius: var(--radius-pill);
flex-shrink: 0;
}
.design-kanban-list {
display: flex;
flex-direction: column;
gap: 8px;
overflow-y: auto;
/* Keep the scrollbar gutter from shifting the list when content grows. */
padding-right: 4px;
margin-right: -4px;
flex: 1 1 auto;
min-height: 0;
}
.design-kanban-empty {
color: var(--text-faint);
font-size: 13px;
text-align: center;
padding: 20px 0;
}
.design-kanban-card {
position: relative;
background: var(--bg-panel);
border: 1px solid var(--border-soft);
border-radius: var(--radius);
padding: 12px 14px;
display: flex;
flex-direction: column;
gap: 6px;
cursor: pointer;
transition: border-color 0.15s ease, box-shadow 0.15s ease, transform 0.15s ease;
box-shadow: var(--shadow-xs);
}
.design-kanban-card:hover {
border-color: var(--border-strong);
box-shadow: var(--shadow-sm);
transform: translateY(-1px);
}
.design-kanban-card:active {
transform: none;
}
.design-kanban-card:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
border-color: var(--border-strong);
}
.design-kanban-card::before {
content: '';
position: absolute;
left: -1px;
top: -1px;
bottom: -1px;
width: 3px;
border-radius: var(--radius) 0 0 var(--radius);
background: var(--text-muted);
}
.design-kanban-card.status-running::before { background: var(--accent); }
.design-kanban-card.status-awaiting_input::before { background: var(--amber); }
.design-kanban-card.status-succeeded::before { background: var(--green); }
.design-kanban-card.status-failed::before { background: var(--red); }
.design-kanban-card.status-not_started::before,
.design-kanban-card.status-queued::before,
.design-kanban-card.status-canceled::before { background: var(--text-muted); }
.design-kanban-card-name {
font-size: 13px;
font-weight: 500;
color: var(--text-strong);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
/* Reserve room for the absolutely-positioned close button. */
padding-right: 20px;
}
.design-kanban-card-meta {
font-size: 12px;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.design-kanban-card-meta .ds {
color: var(--text-strong);
font-weight: 500;
}
/* Honor user motion preferences for the new hover transform / transitions
introduced alongside the kanban view. */
@media (prefers-reduced-motion: reduce) {
.design-card,
.design-kanban-card {
transition: none;
}
.design-card:hover,
.design-kanban-card:hover {
transform: none;
}
}
/* Examples gallery */
.examples-panel { gap: 32px; }
.example-card {
display: grid;
grid-template-columns: 2fr 1fr;
gap: 24px;
align-items: center;
}
.example-preview {
position: relative;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius);
height: 320px;
overflow: hidden;
}
.example-preview iframe {
width: 100%; height: 100%; border: none; background: white; pointer-events: none;
}
.example-preview-placeholder {
position: absolute; inset: 0;
display: flex; align-items: center; justify-content: center;
color: var(--text-muted); font-size: 12px;
}
.example-meta { display: flex; flex-direction: column; gap: 12px; }
.example-name { font-size: 18px; font-weight: 600; letter-spacing: -0.01em; }
.example-prompt {
font-size: 13px;
color: var(--text-muted);
line-height: 1.55;
font-style: italic;
}
.example-cta { align-self: flex-start; padding: 8px 18px; }
.example-tag {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.06em;
padding: 2px 8px;
border-radius: var(--radius-pill);
background: var(--accent);
color: white;
flex-shrink: 0;
}
/* Design systems gallery — masonry-style cards with lazy showcase iframes
serving as thumbnails. The grid mirrors the prompt-templates and example
gallery surfaces so the three browse tabs feel uniform. */
.ds-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
gap: 16px;
}
.ds-card {
display: flex;
flex-direction: column;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
cursor: pointer;
transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}
.ds-card:hover {
border-color: var(--border-strong);
transform: translateY(-1px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.06);
}
.ds-card:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.ds-card.active {
border-color: var(--accent);
box-shadow: 0 0 0 2px var(--accent-tint);
}
.ds-card-thumb {
position: relative;
width: 100%;
aspect-ratio: 4 / 3;
background: var(--bg-subtle);
overflow: hidden;
border-bottom: 1px solid var(--border);
}
.ds-card-thumb iframe {
width: 200%;
height: 200%;
border: none;
display: block;
background: white;
transform: scale(0.5);
transform-origin: top left;
pointer-events: none;
}
.ds-card-thumb-fallback {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
}
.ds-card-thumb-swatches {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
width: 100%;
height: 100%;
}
.ds-card-thumb-swatches > span { display: block; }
.ds-card-thumb-overlay {
position: absolute;
right: 8px;
bottom: 8px;
background: rgba(15, 15, 18, 0.78);
color: #fff;
font-size: 10px;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 4px 10px;
border-radius: 999px;
opacity: 0;
transition: opacity 0.15s ease;
}
.ds-card:hover .ds-card-thumb-overlay,
.ds-card-thumb:focus-visible .ds-card-thumb-overlay {
opacity: 1;
}
.ds-card-meta {
display: flex;
flex-direction: column;
gap: 6px;
padding: 12px 14px 14px;
flex: 1;
}
.ds-card-title-row {
display: flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.ds-card-title {
font-size: 14px;
font-weight: 600;
color: var(--text);
letter-spacing: -0.005em;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
flex: 1;
min-width: 0;
}
.ds-card-badge {
font-size: 9px;
font-weight: 600;
letter-spacing: 0.06em;
padding: 2px 6px;
background: var(--accent-soft);
color: var(--accent);
border-radius: 4px;
flex-shrink: 0;
}
.ds-card-summary {
font-size: 12px;
color: var(--text-muted);
line-height: 1.45;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.ds-card-footer {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
margin-top: auto;
padding-top: 6px;
}
.ds-card-category {
font-size: 10px;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text-muted);
}
.ds-card-swatches {
display: inline-flex;
align-items: center;
border-radius: 6px;
border: 1px solid var(--border);
overflow: hidden;
flex-shrink: 0;
height: 18px;
}
.ds-card-swatches > span {
display: block;
width: 14px;
height: 100%;
}
.ds-card-swatches > span + span {
border-left: 1px solid rgba(0, 0, 0, 0.05);
}
/* Legacy list classes kept for any consumer outside the tab — the gallery
itself no longer renders these. Safe to remove once nothing references
them. */
.ds-list { display: flex; flex-direction: column; gap: 8px; }
.ds-row {
display: flex;
align-items: center;
gap: 12px;
padding: 14px 16px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
}
.ds-row:hover { border-color: var(--border-strong); }
.ds-row.active { background: var(--accent-tint); border-color: var(--accent); }
.ds-row-body { flex: 1; min-width: 0; }
.ds-row-title {
font-weight: 500;
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.ds-row-default {
font-size: 9px;
font-weight: 600;
letter-spacing: 0.06em;
padding: 2px 6px;
background: var(--accent-soft);
color: var(--accent);
border-radius: 4px;
}
.ds-row-summary { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
.ds-row-swatches {
display: inline-flex;
align-items: center;
gap: 0;
border-radius: 6px;
border: 1px solid var(--border);
overflow: hidden;
flex-shrink: 0;
height: 24px;
}
.ds-row-swatch {
display: block;
width: 16px;
height: 100%;
}
.ds-row-swatch + .ds-row-swatch { border-left: 1px solid rgba(0, 0, 0, 0.05); }
@media (max-width: 900px) {
.entry {
grid-template-columns: 1fr !important;
height: 100%;
min-height: 0;
}
.entry-side {
width: 100% !important;
min-width: 0;
max-width: none;
border-right: none;
border-bottom: 1px solid var(--border);
}
.entry-side-resizer { display: none; }
.example-card { grid-template-columns: 1fr; }
.example-preview { height: 240px; }
}
/* ============================================================
File workspace — tabs + viewer
============================================================ */
.workspace {
display: flex;
flex-direction: column;
min-height: 0;
background: var(--bg);
flex: 1;
}
.ws-tabs-shell {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
height: 44px;
position: sticky;
top: 0;
z-index: 4;
}
.ws-tabs-bar {
display: flex;
align-items: center;
gap: 2px;
overflow-x: auto;
overflow-y: hidden;
flex-wrap: nowrap;
flex: 1 1 auto;
min-width: 0;
height: 100%;
}
.ws-tab {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
background: transparent;
border: none;
border-radius: var(--radius-sm);
font-size: 12.5px;
cursor: pointer;
flex-shrink: 0;
max-width: 220px;
color: var(--text-muted);
transition: background 120ms ease, color 120ms ease;
}
.ws-tab:hover { background: var(--bg-subtle); color: var(--text); }
.ws-tab:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.ws-tab.active {
background: var(--bg-subtle);
color: var(--text);
font-weight: 500;
}
.ws-tab .tab-icon {
font-size: 13px;
color: var(--text-muted);
width: 14px;
text-align: center;
}
.ws-tab.active .tab-icon { color: var(--text); }
.ws-tab-label {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 180px;
}
.ws-live-artifact-badges {
flex-wrap: nowrap;
max-width: 145px;
overflow: hidden;
}
.ws-live-artifact-badges .live-artifact-badge:not(.live):not(.refreshing):not(.refresh-failed):not(.archived) {
display: none;
}
.ws-tab-close {
border: none;
background: transparent;
padding: 0 2px;
font-size: 14px;
line-height: 1;
color: var(--text-faint);
border-radius: 4px;
margin-left: 2px;
width: 16px;
height: 16px;
display: inline-flex;
align-items: center;
justify-content: center;
}
.ws-tab-close:hover { background: var(--border); color: var(--text); }
.ws-tab.design-files-tab {
font-weight: 500;
color: var(--text);
}
.ws-tabs-actions { display: inline-flex; gap: 4px; align-items: center; }
.ws-focus-toggle {
display: inline-flex;
align-items: center;
gap: 6px;
height: 28px;
padding: 0 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
background: var(--bg);
color: var(--text-muted);
font-size: 12px;
white-space: nowrap;
flex-shrink: 0;
}
.ws-focus-toggle:hover {
background: var(--bg-subtle);
color: var(--text);
border-color: var(--border-strong);
}
.ws-focus-toggle:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.ws-tab-action {
padding: 4px 12px;
font-size: 12.5px;
background: transparent;
border: 1px solid transparent;
border-radius: var(--radius-sm);
color: var(--text-muted);
}
.ws-tab-action:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); border-color: transparent; }
.ws-tab-action.share {
background: var(--text);
color: var(--bg);
border-color: var(--text);
font-weight: 500;
}
.ws-tab-action.share:hover:not(:disabled) {
background: #000;
border-color: #000;
}
.ws-body {
flex: 1;
min-height: 0;
display: flex;
flex-direction: column;
}
/* -------- Design Files panel (full right pane) ---------------------- */
.df-panel {
flex: 1;
display: grid;
grid-template-columns: minmax(0, 1fr) minmax(0, 380px);
min-height: 0;
background: var(--bg);
}
.df-panel.no-preview { grid-template-columns: minmax(0, 1fr); }
.df-main {
display: flex;
flex-direction: column;
min-height: 0;
background: var(--bg);
border-right: 1px solid var(--border);
}
.df-main:last-child { border-right: none; }
.df-head {
display: flex;
align-items: center;
gap: 6px;
padding: 10px 16px;
border-bottom: 1px solid var(--border);
background: var(--bg);
position: sticky;
top: 0;
z-index: 3;
}
.df-head .icon-only {
width: 28px;
height: 28px;
padding: 0;
background: transparent;
border: none;
border-radius: 6px;
color: var(--text-muted);
display: inline-flex;
align-items: center;
justify-content: center;
}
.df-head .icon-only:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); }
.df-head .crumbs {
font-size: 12.5px;
color: var(--text);
margin-left: 4px;
font-weight: 500;
}
.df-head .df-actions {
margin-left: auto;
display: inline-flex;
gap: 4px;
}
.df-head .df-actions button {
background: transparent;
border: 1px solid transparent;
color: var(--text-muted);
padding: 5px 10px;
font-size: 12.5px;
border-radius: var(--radius-sm);
display: inline-flex;
align-items: center;
gap: 6px;
}
.df-head .df-actions button:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); }
.df-body {
flex: 1;
min-height: 0;
overflow-y: auto;
padding: 12px 0 0;
}
.df-section { display: flex; flex-direction: column; gap: 0; }
.df-section + .df-section { margin-top: 6px; }
.df-section-label {
font-size: 10.5px;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--text-faint);
font-weight: 600;
padding: 12px 20px 6px;
}
.df-section-count {
margin-left: 8px;
color: var(--text-faint);
font-weight: 500;
letter-spacing: 0;
}
.df-row {
display: grid;
grid-template-columns: 28px 36px 1fr auto auto;
align-items: center;
gap: 12px;
padding: 10px 20px;
background: transparent;
border: none;
border-radius: 0;
text-align: left;
cursor: pointer;
width: 100%;
font: inherit;
color: inherit;
position: relative;
transition: background 120ms ease;
}
.df-row:hover { background: var(--bg-subtle); }
.df-row.active { background: var(--blue-bg); color: var(--text); }
.df-row.active .df-row-name { color: var(--text-strong); }
.df-row.selected { background: var(--blue-bg); }
.df-row-check {
display: inline-flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 13px;
color: var(--text-muted);
user-select: none;
width: 24px;
height: 24px;
border-radius: 4px;
transition: background 120ms ease, color 120ms ease;
}
.df-row-check:hover { background: var(--border); color: var(--text); }
.df-row-check[aria-checked="true"] { color: var(--accent-strong); }
.df-select-all {
background: none;
border: none;
color: var(--text-muted);
cursor: pointer;
font: inherit;
font-size: 11px;
font-weight: 500;
margin-left: auto;
padding: 2px 8px;
border-radius: 4px;
transition: background 120ms ease, color 120ms ease;
}
.df-select-all:hover { background: var(--bg-subtle); color: var(--text); }
.df-row-icon {
width: 32px;
height: 32px;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
border-radius: 6px;
background: var(--bg-subtle);
color: var(--text-muted);
font-size: 14px;
position: relative;
}
.df-row-icon[data-kind="folder"] { background: var(--bg-muted); color: var(--text-soft); }
.df-row-icon[data-kind="html"] { background: var(--accent-tint); color: var(--accent-strong); }
.df-row-icon[data-kind="image"] { background: var(--green-bg); color: var(--green); }
.df-row-icon[data-kind="code"] { background: #fff7d8; color: #8c6700; }
.df-row-icon[data-kind="text"] { background: var(--bg-subtle); color: var(--text-muted); }
.df-row-icon[data-kind="sketch"] { background: var(--purple-bg); color: var(--purple); }
.df-row-name-wrap { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.df-row-name {
font-size: 13px;
font-weight: 500;
color: var(--text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.df-row-sub {
font-size: 11px;
color: var(--text-muted);
display: inline-flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.df-row-time {
font-size: 11.5px;
color: var(--text-muted);
font-variant-numeric: tabular-nums;
white-space: nowrap;
}
.df-row-menu {
background: transparent;
border: none;
padding: 4px 6px;
color: var(--text-muted);
font-size: 16px;
border-radius: 4px;
opacity: 0;
transition: opacity 120ms ease;
}
.df-row:hover .df-row-menu { opacity: 1; }
.df-row-menu:hover { background: var(--border); color: var(--text); }
.df-section-more {
margin: 6px 20px 10px;
width: auto;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
font-size: 12px;
line-height: 1;
}
.df-section-more:hover:not(:disabled) {
background: var(--bg-muted);
color: var(--text);
}
.df-row-collapse {
background: transparent;
border: none;
color: var(--text-muted);
padding: 0;
width: 18px;
text-align: center;
font-size: 12px;
cursor: pointer;
}
.df-empty {
padding: 48px 24px;
text-align: center;
color: var(--text-muted);
font-size: 13px;
}
.df-drop {
margin: 18px 16px 16px;
padding: 16px;
border: 1px dashed var(--border-strong);
border-radius: var(--radius);
background: var(--bg-panel);
display: flex;
flex-direction: column;
align-items: center;
gap: 6px;
text-align: center;
color: var(--text-muted);
}
.df-drop.dragging {
border-color: var(--accent);
background: color-mix(in srgb, var(--accent) 10%, var(--bg-panel));
color: var(--text);
}
.df-drop .label {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.1em;
color: var(--text-faint);
display: inline-flex;
align-items: center;
gap: 6px;
font-weight: 600;
}
.df-drop .desc {
font-size: 12px;
line-height: 1.5;
max-width: 56ch;
}
/* Right preview pane in design files */
.df-preview {
display: flex;
flex-direction: column;
min-height: 0;
background: var(--bg-panel);
border-left: 1px solid var(--border);
}
.df-preview-empty {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-faint);
font-size: 13px;
padding: 32px;
}
.df-preview-thumb {
margin: 16px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg);
overflow: hidden;
aspect-ratio: 16/10;
flex-shrink: 0;
position: relative;
}
.df-preview-thumb iframe,
.df-preview-thumb img,
.df-preview-thumb video {
width: 100%; height: 100%; border: none; background: white; object-fit: cover; display: block;
}
.df-preview-thumb audio {
width: calc(100% - 24px);
position: absolute;
left: 12px;
bottom: 12px;
}
.df-preview-meta {
padding: 0 16px 16px;
display: flex;
flex-direction: column;
gap: 6px;
}
.df-preview-name {
font-size: 14px;
font-weight: 600;
color: var(--text-strong);
word-break: break-word;
}
.df-preview-kind { font-size: 12px; color: var(--text-muted); }
.df-preview-stats { font-size: 11.5px; color: var(--text-muted); }
.df-preview-actions { display: inline-flex; gap: 6px; margin-top: 6px; flex-wrap: wrap; }
.df-preview-actions button {
font-size: 12px;
padding: 5px 10px;
background: var(--bg-panel);
border: 1px solid var(--border);
color: var(--text);
border-radius: var(--radius-sm);
display: inline-flex;
align-items: center;
gap: 4px;
}
.df-preview-actions button:hover { background: var(--bg-subtle); border-color: var(--border-strong); }
/* Row context menu */
.df-row-popover {
position: fixed;
z-index: 200;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
box-shadow: var(--shadow-md);
padding: 4px;
min-width: 160px;
display: flex;
flex-direction: column;
}
.df-row-popover button {
background: transparent;
border: none;
padding: 7px 10px;
font-size: 12.5px;
text-align: left;
border-radius: 4px;
color: var(--text);
}
.df-row-popover button:hover { background: var(--bg-subtle); }
.df-row-popover button.danger { color: var(--red); }
.df-row-popover button.danger:hover { background: var(--red-bg); }
/* -------- Viewer ---------------------------------------------------- */
.viewer {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
}
.viewer-toolbar {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 14px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
font-size: 12.5px;
color: var(--text-muted);
gap: 8px;
height: 44px;
flex-shrink: 0;
}
.viewer-toolbar-left { display: inline-flex; align-items: center; gap: 8px; }
.viewer-toolbar-actions { display: inline-flex; gap: 2px; align-items: center; }
.viewer-toolbar .icon-only,
.viewer-toolbar-actions .icon-only {
width: 28px;
height: 28px;
padding: 0;
background: transparent;
border: none;
border-radius: 6px;
color: var(--text-muted);
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 14px;
}
.viewer-toolbar .icon-only:hover:not(:disabled),
.viewer-toolbar-actions .icon-only:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); }
.viewer-action {
display: inline-flex;
align-items: center;
gap: 5px;
padding: 4px 10px;
background: transparent;
border: none;
border-radius: var(--radius-sm);
color: var(--text-muted);
font-size: 12.5px;
white-space: nowrap;
}
.viewer-action:hover:not(:disabled) { background: var(--bg-subtle); color: var(--text); }
.viewer-action.active {
background: var(--accent-tint);
color: var(--accent-strong);
}
.viewer-action.primary {
background: var(--accent);
border: 1px solid var(--accent);
color: white;
}
.viewer-action.primary:hover:not(:disabled) {
background: var(--accent-hover);
border-color: var(--accent-hover);
color: white;
}
/* Primary actions support a subtle in-flight affordance via data-running. Keeps
layout stable (unlike :disabled-only) so locale text width doesn't jump. */
.viewer-action.primary[data-running='true'] {
opacity: 0.75;
cursor: progress;
}
/* Preview-only controls: keep layout stable across modes.
When inactive, reserve the same horizontal slot but fully disable interaction. */
.viewer-preview-controls {
display: inline-flex;
gap: 2px;
align-items: center;
transition: opacity 140ms ease;
}
.viewer-preview-controls[data-active='false'] {
opacity: 0;
pointer-events: none;
user-select: none;
}
.viewer-zoom-level {
min-width: 60px;
justify-content: center;
}
.viewer-divider {
width: 1px;
height: 18px;
background: var(--border);
margin: 0 4px;
}
.viewer-toggle {
display: inline-flex;
align-items: center;
gap: 6px;
font-size: 12.5px;
color: var(--text-muted);
padding: 4px 10px;
border-radius: var(--radius-sm);
white-space: nowrap;
}
.viewer-toggle .switch {
position: relative;
width: 28px;
height: 16px;
background: var(--bg-muted);
border-radius: 999px;
border: 1px solid var(--border-strong);
transition: background 120ms ease;
}
.viewer-toggle .switch::after {
content: '';
position: absolute;
top: 1px;
left: 1px;
width: 12px; height: 12px;
background: var(--bg-panel);
border-radius: 50%;
transition: transform 120ms ease;
box-shadow: var(--shadow-xs);
}
.viewer-toggle.on .switch,
.viewer-toggle.active .switch { background: var(--text); border-color: var(--text); }
.viewer-toggle.on .switch::after,
.viewer-toggle.active .switch::after { transform: translateX(12px); }
.viewer-tabs { display: inline-flex; gap: 2px; }
.viewer-tab {
background: transparent;
border: none;
padding: 4px 10px;
font-size: 12px;
border-radius: var(--radius-sm);
color: var(--text-muted);
white-space: nowrap;
}
.viewer-tab:hover { background: var(--bg-subtle); color: var(--text); }
.viewer-tab.active {
background: var(--bg-subtle);
color: var(--text);
font-weight: 500;
}
.viewer-meta { font-size: 12px; color: var(--text-muted); }
.ghost-link {
font-size: 12px;
color: var(--text-muted);
text-decoration: none;
padding: 4px 10px;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
display: inline-flex;
align-items: center;
gap: 4px;
}
.ghost-link:hover { background: var(--bg-subtle); color: var(--text); }
.viewer-body {
flex: 1;
min-height: 0;
position: relative;
background: var(--bg);
overflow: auto;
}
.live-artifact-refresh-notice {
position: sticky;
top: 0;
z-index: 2;
display: flex;
align-items: center;
justify-content: space-between;
gap: 12px;
padding: 9px 14px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
color: var(--text-muted);
font-size: 12.5px;
}
.live-artifact-refresh-notice-copy {
display: inline-flex;
align-items: center;
gap: 8px;
min-width: 0;
}
.live-artifact-refresh-notice strong {
color: var(--text);
font-weight: 600;
}
.live-artifact-refresh-notice .icon-only {
width: 24px;
height: 24px;
flex: 0 0 auto;
border: none;
border-radius: var(--radius-sm);
background: transparent;
color: inherit;
font-size: 16px;
}
.live-artifact-refresh-notice .icon-only:hover {
background: color-mix(in srgb, currentColor 12%, transparent);
}
.live-artifact-refresh-notice.running {
background: var(--bg-subtle);
}
.live-artifact-refresh-notice.success {
background: var(--green-bg);
border-color: var(--green-border);
color: var(--green);
}
.live-artifact-refresh-notice.error {
background: var(--red-bg);
border-color: var(--red-border);
color: var(--red);
}
.live-artifact-refresh-notice.success strong,
.live-artifact-refresh-notice.error strong {
color: inherit;
}
.live-artifact-code-panel {
display: flex;
flex-direction: column;
height: 100%;
min-height: 0;
background: var(--bg);
}
.live-artifact-code-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
padding: 12px 16px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
}
.live-artifact-code-copy {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.live-artifact-code-copy strong {
font-size: 13px;
color: var(--text);
}
.live-artifact-code-copy span {
font-size: 12px;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.live-artifact-code-tabs {
flex-shrink: 0;
}
.live-artifact-code-panel pre.viewer-source {
flex: 1 1 auto;
min-height: 0;
}
/* ============================================================
Live artifact — Refresh history panel
============================================================ */
.live-artifact-refresh-panel {
display: flex;
flex-direction: column;
gap: 18px;
padding: 20px 22px 28px;
color: var(--text);
background: var(--bg);
min-height: 100%;
}
.live-artifact-refresh-hero {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 20px;
padding: 16px 18px;
border: 1px solid var(--border);
border-radius: 10px;
background: var(--bg-panel);
box-shadow: var(--shadow-xs, 0 1px 2px rgba(16, 24, 40, 0.04));
}
.live-artifact-refresh-hero-main {
display: flex;
flex-direction: column;
gap: 8px;
min-width: 0;
flex: 1 1 auto;
}
.live-artifact-refresh-hero-desc {
margin: 0;
color: var(--text-muted);
font-size: 12.5px;
line-height: 1.5;
}
.live-artifact-refresh-hero-meta {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 6px;
flex: 0 0 auto;
}
.live-artifact-refresh-hero-metric {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 2px;
text-align: right;
}
.live-artifact-refresh-label {
font-size: 10.5px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--text-muted);
}
.live-artifact-refresh-value {
font-size: 14px;
font-weight: 600;
color: var(--text);
font-variant-numeric: tabular-nums;
}
.live-artifact-refresh-value.muted {
color: var(--text-muted);
font-weight: 500;
}
.live-artifact-refresh-sub {
font-size: 11.5px;
color: var(--text-muted);
font-variant-numeric: tabular-nums;
}
/* Refresh status badges reuse the .live-artifact-badge pill shape with tone mixins */
.live-artifact-badge.refresh-status {
text-transform: uppercase;
letter-spacing: 0.04em;
}
.live-artifact-badge.refresh-status.tone-neutral {
color: var(--text-muted);
border-color: var(--border);
background: var(--bg-panel);
}
.live-artifact-badge.refresh-status.tone-running {
color: #1d4ed8;
border-color: rgba(29, 78, 216, 0.22);
background: rgba(29, 78, 216, 0.08);
}
.live-artifact-badge.refresh-status.tone-success {
color: var(--green);
border-color: var(--green-border);
background: var(--green-bg);
}
.live-artifact-badge.refresh-status.tone-warning {
color: var(--amber);
border-color: color-mix(in srgb, var(--amber) 28%, transparent);
background: var(--amber-bg);
}
.live-artifact-badge.refresh-status.tone-error {
color: var(--red);
border-color: var(--red-border);
background: var(--red-bg);
}
.live-artifact-refresh-facts {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
}
.live-artifact-refresh-fact {
display: flex;
flex-direction: column;
gap: 4px;
padding: 12px 14px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-panel);
min-width: 0;
}
.live-artifact-refresh-fact .live-artifact-refresh-value {
font-size: 13px;
font-weight: 600;
}
.live-artifact-refresh-section {
display: flex;
flex-direction: column;
gap: 10px;
}
.live-artifact-refresh-section-header {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 12px;
}
.live-artifact-refresh-section-header h4 {
margin: 0;
font-size: 12.5px;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text-muted);
}
.live-artifact-refresh-hint {
font-size: 11.5px;
color: var(--text-muted);
}
.live-artifact-refresh-empty {
padding: 16px 18px;
border: 1px dashed var(--border);
border-radius: 8px;
background: var(--bg-panel);
color: var(--text-muted);
font-size: 12.5px;
line-height: 1.5;
}
.live-artifact-refresh-empty em {
font-style: normal;
font-weight: 600;
color: var(--text);
}
.live-artifact-refresh-timeline {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
gap: 0;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-panel);
overflow: hidden;
}
.live-artifact-refresh-event {
display: grid;
grid-template-columns: 20px 1fr;
column-gap: 12px;
padding: 12px 14px;
border-bottom: 1px solid var(--border-soft, var(--border));
position: relative;
}
.live-artifact-refresh-event:last-child {
border-bottom: none;
}
.live-artifact-refresh-event-dot {
width: 10px;
height: 10px;
border-radius: 999px;
margin-top: 5px;
justify-self: center;
background: var(--border-strong);
box-shadow: 0 0 0 3px var(--bg-panel);
}
.live-artifact-refresh-event.tone-running .live-artifact-refresh-event-dot {
background: #1d4ed8;
animation: liveArtifactRefreshPulse 1.5s ease-in-out infinite;
}
.live-artifact-refresh-event.tone-success .live-artifact-refresh-event-dot {
background: var(--green);
}
.live-artifact-refresh-event.tone-error .live-artifact-refresh-event-dot {
background: var(--red);
}
@keyframes liveArtifactRefreshPulse {
0%, 100% { opacity: 1; transform: scale(1); }
50% { opacity: 0.55; transform: scale(0.85); }
}
.live-artifact-refresh-event-body {
display: flex;
flex-direction: column;
gap: 4px;
min-width: 0;
}
.live-artifact-refresh-event-row {
display: inline-flex;
align-items: center;
gap: 10px;
flex-wrap: wrap;
}
.live-artifact-refresh-event-time {
font-size: 11.5px;
color: var(--text-muted);
font-variant-numeric: tabular-nums;
}
.live-artifact-refresh-event-detail {
font-size: 12.5px;
color: var(--text);
line-height: 1.5;
word-break: break-word;
}
.live-artifact-refresh-tiles {
list-style: none;
margin: 0;
padding: 0;
display: flex;
flex-direction: column;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-panel);
overflow: hidden;
}
.live-artifact-refresh-tile {
display: grid;
grid-template-columns: 1fr auto;
column-gap: 12px;
row-gap: 6px;
padding: 12px 14px;
border-bottom: 1px solid var(--border-soft, var(--border));
align-items: center;
}
.live-artifact-refresh-tile:last-child {
border-bottom: none;
}
.live-artifact-refresh-tile-main {
display: flex;
flex-direction: column;
gap: 2px;
min-width: 0;
}
.live-artifact-refresh-tile-title {
font-size: 13px;
font-weight: 500;
color: var(--text);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.live-artifact-refresh-tile-meta code {
font-size: 11px;
font-family: var(--mono);
color: var(--text-muted);
background: var(--bg-subtle);
padding: 1px 6px;
border-radius: 4px;
}
.live-artifact-refresh-tile-side {
display: inline-flex;
justify-self: end;
}
.live-artifact-refresh-tile-error {
grid-column: 1 / -1;
font-size: 11.5px;
color: var(--red);
background: var(--red-bg);
border: 1px solid var(--red-border);
border-radius: 6px;
padding: 6px 10px;
line-height: 1.5;
word-break: break-word;
}
.live-artifact-refresh-tile-error.neutral {
color: var(--text-muted);
background: var(--bg-subtle);
border-color: var(--border);
}
.live-artifact-refresh-kv {
margin: 0;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
gap: 10px;
padding: 14px 16px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-panel);
}
.live-artifact-refresh-kv > div {
display: flex;
flex-direction: column;
gap: 3px;
min-width: 0;
}
.live-artifact-refresh-kv dt {
font-size: 10.5px;
font-weight: 600;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--text-muted);
}
.live-artifact-refresh-kv dd {
margin: 0;
font-size: 13px;
color: var(--text);
word-break: break-word;
}
.live-artifact-refresh-kv dd code {
font-family: var(--mono);
font-size: 12px;
background: var(--bg-subtle);
padding: 1px 6px;
border-radius: 4px;
}
.live-artifact-refresh-raw {
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-panel);
overflow: hidden;
}
.live-artifact-refresh-raw > summary {
cursor: pointer;
padding: 10px 14px;
font-size: 12px;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--text-muted);
user-select: none;
list-style: none;
}
.live-artifact-refresh-raw > summary::-webkit-details-marker { display: none; }
.live-artifact-refresh-raw > summary::before {
content: '▸';
display: inline-block;
width: 1em;
transition: transform 120ms ease;
color: var(--text-faint);
}
.live-artifact-refresh-raw[open] > summary::before {
transform: rotate(90deg);
}
.live-artifact-refresh-raw > summary:hover {
background: var(--bg-subtle);
}
.live-artifact-refresh-raw-note {
margin: 0;
padding: 0 14px 10px;
color: var(--text-muted);
font-size: 11.5px;
line-height: 1.5;
}
.live-artifact-refresh-raw pre.viewer-source {
border-top: 1px solid var(--border);
min-height: 0;
max-height: 320px;
overflow: auto;
}
@media (max-width: 640px) {
.live-artifact-refresh-hero {
flex-direction: column;
align-items: stretch;
}
.live-artifact-refresh-hero-meta {
align-items: flex-start;
}
.live-artifact-refresh-hero-metric {
align-items: flex-start;
text-align: left;
}
}
.viewer-body iframe {
width: 100%;
height: 100%;
border: none;
background: white;
}
.comment-preview-layer {
position: relative;
width: 100%;
height: 100%;
min-height: 0;
}
.comment-frame-clip {
position: absolute;
inset: 0;
overflow: hidden;
}
.comment-overlay-layer {
position: absolute;
inset: 0;
z-index: 3;
pointer-events: none;
}
.board-pod-stroke {
position: absolute;
inset: 0;
width: 100%;
height: 100%;
overflow: visible;
pointer-events: none;
}
.board-pod-stroke polyline {
fill: none;
stroke: rgba(22, 119, 255, 0.95);
stroke-width: 3;
stroke-linecap: round;
stroke-linejoin: round;
filter: drop-shadow(0 0 4px rgba(22, 119, 255, 0.28));
}
.comment-target-overlay {
position: absolute;
pointer-events: none;
border: 1px solid var(--comment-overlay-border, #1677ff);
background: var(--comment-overlay-bg, rgba(22, 119, 255, 0.24));
box-shadow: 0 0 0 1px var(--comment-overlay-ring, rgba(22, 119, 255, 0.18));
}
.comment-target-overlay.selected {
border-width: 2px;
}
.comment-target-overlay-label {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border: 0;
}
.comment-saved-marker {
position: absolute;
pointer-events: none;
}
.comment-saved-outline {
position: absolute;
inset: 0;
border: 1px dashed rgba(22, 119, 255, 0.72);
background: rgba(22, 119, 255, 0.08);
}
.comment-saved-pin {
position: absolute;
z-index: 2;
left: -8px;
top: -8px;
min-width: 18px;
height: 18px;
padding: 0 5px;
border: 1px solid #0958d9;
border-radius: var(--radius-pill);
background: #1677ff;
color: white;
font-size: 10px;
font-weight: 700;
line-height: 16px;
box-shadow: var(--shadow-sm);
pointer-events: auto;
}
.comment-saved-pin:hover {
background: #0958d9;
transform: translateY(-1px);
}
.comment-popover {
position: absolute;
left: 14px;
top: 14px;
z-index: 4;
width: min(320px, calc(100% - 28px));
padding: 10px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-panel);
box-shadow: var(--shadow-lg);
}
.comment-popover-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
margin-bottom: 8px;
}
.comment-popover-head div {
display: grid;
gap: 1px;
}
.comment-popover-head strong { font-size: 13px; }
.comment-popover-head span {
color: var(--text-muted);
font-size: 12px;
}
.board-pod-summary {
display: grid;
gap: 6px;
margin-bottom: 8px;
padding: 8px;
border: 1px solid var(--border-soft);
border-radius: var(--radius-sm);
background: var(--bg-subtle);
}
.board-pod-summary strong {
font-size: 12px;
}
.board-pod-members {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.board-pod-chip {
padding: 3px 7px;
border: 1px solid var(--border-soft);
border-radius: var(--radius-pill);
background: var(--bg-panel);
color: var(--text-muted);
font-size: 11px;
}
.board-note-list {
display: grid;
gap: 6px;
margin-bottom: 8px;
}
.board-note-item {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
padding: 8px 9px;
border: 1px solid var(--border-soft);
border-radius: var(--radius-sm);
background: var(--bg-subtle);
font-size: 12px;
}
.board-note-item span {
color: var(--text);
}
.comment-popover textarea {
min-height: 78px;
max-height: 120px;
resize: vertical;
}
.comment-popover-actions {
display: flex;
justify-content: space-between;
align-items: center;
gap: 8px;
margin-top: 8px;
}
.comment-popover-remove {
color: var(--red);
background: transparent;
border-color: transparent;
}
.comment-popover-remove:hover:not(:disabled) {
background: var(--red-bg);
border-color: var(--red-border);
}
.comments-panel {
display: flex;
flex-direction: column;
gap: 12px;
padding: 14px;
overflow: auto;
}
.comments-section {
display: flex;
flex-direction: column;
gap: 8px;
}
.comments-section h3 {
margin: 0;
color: var(--text-muted);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
}
.comments-empty {
margin: 0;
padding: 10px 12px;
border: 1px dashed var(--border);
border-radius: var(--radius);
color: var(--text-faint);
font-size: 12px;
}
.comment-card {
display: grid;
gap: 5px;
padding: 9px 10px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-panel);
box-shadow: var(--shadow-xs);
}
.comment-card.attached {
border-color: var(--accent-soft);
background: var(--accent-tint);
}
.comment-card-top {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
min-width: 0;
}
.comment-card-top strong {
min-width: 0;
overflow: hidden;
color: var(--accent-strong);
font-size: 13px;
font-weight: 700;
text-overflow: ellipsis;
white-space: nowrap;
}
.comment-card-actions {
display: inline-flex;
align-items: center;
gap: 6px;
flex: 0 0 auto;
}
.comment-card p {
margin: 0;
color: var(--text);
font-size: 12.5px;
line-height: 1.35;
overflow-wrap: anywhere;
}
.comment-card-action {
flex: 0 0 auto;
padding: 3px 8px;
border: 1px solid var(--border);
border-radius: var(--radius-pill);
background: var(--bg);
color: var(--text-muted);
font-size: 11.5px;
}
.comment-card-action:hover {
border-color: var(--accent-soft);
color: var(--accent-strong);
}
.comment-card-action.danger {
color: var(--red);
}
.comment-card-action.danger:hover {
border-color: var(--red-border);
background: var(--red-bg);
}
.comment-card-meta {
display: flex;
flex-wrap: wrap;
gap: 4px;
color: var(--text-faint);
font-size: 11px;
}
.comment-card-meta span {
max-width: 140px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.comment-card-meta span:not(:last-child)::after {
content: '·';
margin-left: 4px;
color: var(--text-faint);
}
.comments-footer {
display: flex;
justify-content: flex-start;
padding-top: 2px;
}
.comments-footer .primary {
padding: 6px 12px;
font-size: 12px;
}
.comment-history-attachments {
gap: 6px;
}
.viewer-source {
margin: 0;
padding: 16px;
font-family: var(--mono);
font-size: 12px;
line-height: 1.55;
white-space: pre-wrap;
word-break: break-word;
color: var(--text);
background: var(--bg-panel);
min-height: 100%;
}
/* Code viewer with line numbers */
.code-viewer {
background: var(--bg-panel);
margin: 0;
padding: 0;
display: grid;
grid-template-columns: auto 1fr;
font-family: var(--mono);
font-size: 12px;
line-height: 1.6;
min-height: 100%;
}
.code-viewer .gutter {
background: var(--bg);
color: var(--text-faint);
text-align: right;
padding: 16px 12px 16px 16px;
user-select: none;
border-right: 1px solid var(--border-soft);
white-space: pre;
font-variant-numeric: tabular-nums;
}
.code-viewer .lines {
padding: 16px 16px 16px 18px;
white-space: pre;
overflow-x: auto;
color: var(--text);
}
.viewer-empty {
padding: 48px 24px;
text-align: center;
color: var(--text-muted);
font-size: 13px;
}
.document-preview {
max-width: 860px;
margin: 0 auto;
padding: 32px 40px 56px;
color: var(--text);
}
.document-preview h2 {
margin: 0 0 24px;
font-size: 20px;
line-height: 1.25;
}
.document-preview section {
border-top: 1px solid var(--border-soft);
padding-top: 18px;
margin-top: 18px;
}
.document-preview h3 {
margin: 0 0 12px;
font-size: 13px;
color: var(--text-muted);
font-weight: 600;
}
.document-preview p {
margin: 0 0 8px;
font-size: 14px;
line-height: 1.65;
white-space: pre-wrap;
}
.markdown-rendered {
max-width: 900px;
margin: 0 auto;
padding: 24px 28px 40px;
color: var(--text);
line-height: 1.65;
white-space: normal;
}
.markdown-status {
margin: 12px auto 0;
max-width: 900px;
padding: 8px 10px;
border: 1px solid var(--border-soft);
border-radius: 8px;
background: var(--bg-panel);
color: var(--text-muted);
font-size: 12px;
}
.markdown-status-error {
border-color: color-mix(in oklab, var(--danger, #d04b4b) 45%, var(--border-soft));
color: var(--danger, #d04b4b);
}
.markdown-rendered h1,
.markdown-rendered h2,
.markdown-rendered h3,
.markdown-rendered h4,
.markdown-rendered h5,
.markdown-rendered h6 {
margin: 20px 0 10px;
line-height: 1.25;
}
.markdown-rendered p { margin: 10px 0; }
.markdown-rendered ul,
.markdown-rendered ol {
margin: 10px 0;
padding-left: 24px;
}
.markdown-rendered blockquote {
margin: 12px 0;
padding: 8px 12px;
border-left: 3px solid var(--border);
color: var(--text-muted);
background: var(--bg-panel);
}
.markdown-code-block {
position: relative;
}
.markdown-code-copy {
position: absolute;
top: 18px;
right: 18px;
z-index: 1;
border: 1px solid var(--border-soft);
border-radius: 999px;
background: color-mix(in oklab, var(--bg-panel) 92%, black 8%);
color: var(--text-muted);
font: inherit;
font-size: 11px;
font-weight: 600;
line-height: 1;
padding: 7px 10px;
cursor: pointer;
opacity: 0;
transform: translateY(-2px);
transition:
opacity 120ms ease,
transform 120ms ease,
color 120ms ease,
border-color 120ms ease,
background 120ms ease;
}
.markdown-code-block:hover .markdown-code-copy,
.markdown-code-block:focus-within .markdown-code-copy {
opacity: 1;
transform: translateY(0);
}
@media (hover: none) {
.markdown-code-copy {
opacity: 1;
transform: translateY(0);
}
}
.markdown-code-copy:hover,
.markdown-code-copy:focus-visible {
color: var(--text);
border-color: var(--border);
background: var(--bg-elevated, var(--bg));
}
.markdown-code-toast {
position: absolute;
top: 18px;
right: 82px;
z-index: 1;
border-radius: 999px;
background: color-mix(in oklab, var(--accent) 18%, var(--bg-panel));
color: var(--text);
font-size: 11px;
font-weight: 600;
line-height: 1;
padding: 7px 10px;
box-shadow: 0 10px 26px color-mix(in oklab, var(--accent) 18%, transparent);
}
.markdown-rendered pre {
margin: 12px 0;
background: var(--bg-panel);
border: 1px solid var(--border-soft);
border-radius: 8px;
padding: 40px 12px 12px;
overflow: auto;
}
.markdown-rendered code {
font-family: var(--mono);
font-size: 12px;
}
.markdown-rendered a { color: var(--accent); }
.image-body {
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
}
.image-body img {
max-width: 100%;
max-height: 100%;
object-fit: contain;
background: white;
border: 1px solid var(--border);
border-radius: var(--radius-sm);
}
/* Sketch editor */
.sketch-editor {
flex: 1;
display: flex;
flex-direction: column;
min-height: 0;
background: var(--bg);
}
.sketch-toolbar {
display: flex;
align-items: center;
gap: 4px;
padding: 8px 12px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
flex-wrap: wrap;
}
.sketch-tool {
padding: 6px 10px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: 6px;
font-size: 14px;
line-height: 1;
min-width: 32px;
}
.sketch-tool:hover { background: var(--bg-subtle); }
.sketch-tool.active { background: var(--accent); color: white; border-color: var(--accent); }
.sketch-divider { width: 1px; height: 20px; background: var(--border); margin: 0 4px; }
.sketch-color { width: 32px; height: 28px; padding: 0; border: 1px solid var(--border); border-radius: 6px; cursor: pointer; }
.sketch-size { width: 80px; background: transparent; border: none; }
.sketch-spacer { flex: 1; }
.sketch-canvas-wrap { flex: 1; min-height: 0; position: relative; background: var(--bg); }
.sketch-canvas-wrap canvas { display: block; cursor: crosshair; }
/* ===========================================================
Streaming chat: assistant message header, prose, thinking,
tool cards, status pills, grouped action card.
=========================================================== */
.chat-empty-wrap {
flex: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 18px;
padding: 24px 8px;
min-height: 100%;
}
.chat-empty {
color: var(--text-muted);
font-size: 13px;
display: flex;
flex-direction: column;
align-items: center;
text-align: center;
gap: 6px;
max-width: 44ch;
}
.chat-empty-title { font-weight: 600; color: var(--text-strong); font-size: 15px; }
.chat-empty-hint { line-height: 1.6; }
.chat-examples {
display: flex;
flex-direction: column;
gap: 10px;
width: 100%;
max-width: 520px;
}
.chat-example {
position: relative;
display: flex;
align-items: center;
gap: 12px;
width: 100%;
padding: 14px 16px;
text-align: left;
cursor: pointer;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-xs);
color: var(--text);
font: inherit;
overflow: hidden;
transition:
transform 160ms ease,
border-color 160ms ease,
box-shadow 160ms ease,
background-color 160ms ease;
opacity: 0;
animation: chat-example-in 380ms cubic-bezier(0.22, 1, 0.36, 1) forwards;
}
.chat-example::before {
content: '';
position: absolute;
inset: 0;
background: linear-gradient(
135deg,
var(--accent-tint) 0%,
transparent 55%
);
opacity: 0;
transition: opacity 200ms ease;
pointer-events: none;
}
.chat-example:hover {
transform: translateY(-2px);
border-color: var(--accent);
box-shadow: var(--shadow-md);
background: var(--bg-panel);
}
.chat-example:hover::before {
opacity: 1;
}
.chat-example:active {
transform: translateY(0);
}
.chat-example:focus-visible {
outline: 2px solid var(--accent);
outline-offset: 2px;
}
.chat-example-icon {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 36px;
height: 36px;
flex-shrink: 0;
border-radius: var(--radius-sm);
background: var(--accent);
color: #fff;
font-size: 18px;
line-height: 1;
box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04), inset 0 -1px 0 rgba(0, 0, 0, 0.08);
}
.chat-example-body {
position: relative;
display: flex;
flex-direction: column;
gap: 3px;
min-width: 0;
flex: 1;
}
.chat-example-head {
display: flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.chat-example-title {
font-weight: 600;
color: var(--text-strong);
font-size: 13.5px;
}
.chat-example-tag {
font-family: var(--mono);
font-size: 10.5px;
letter-spacing: 0.04em;
text-transform: uppercase;
color: var(--accent);
background: var(--accent-tint);
border: 1px solid var(--accent-soft);
padding: 1px 7px;
border-radius: var(--radius-pill);
line-height: 1.5;
white-space: nowrap;
}
.chat-example-prompt {
color: var(--text-muted);
font-size: 12.5px;
line-height: 1.5;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.chat-example-cta {
position: relative;
display: inline-flex;
align-items: center;
justify-content: center;
width: 24px;
height: 24px;
flex-shrink: 0;
border-radius: 50%;
background: var(--bg-subtle);
color: var(--text-muted);
font-size: 13px;
transition: background-color 160ms ease, color 160ms ease, transform 160ms ease;
}
.chat-example:hover .chat-example-cta {
background: var(--accent);
color: #fff;
transform: translateX(2px);
}
@keyframes chat-example-in {
from {
opacity: 0;
transform: translateY(8px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
.assistant-header {
display: flex;
align-items: center;
gap: 8px;
font-size: 11.5px;
color: var(--text-muted);
margin-bottom: 8px;
}
.assistant-header .dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--text-muted);
}
.assistant-header .dot[data-active="true"] {
background: var(--accent);
animation: pulse 1.2s ease-in-out infinite;
}
.assistant-label { font-weight: 600; color: var(--text-strong); font-size: 12.5px; }
.assistant-stats { font-variant-numeric: tabular-nums; margin-left: auto; }
.assistant-flow {
display: flex;
flex-direction: column;
gap: 8px;
}
.prose-block { line-height: 1.6; color: var(--text); }
.prose-block .md-p { margin: 0; }
.prose-block .md-p + .md-p { margin-top: 8px; }
.prose-block .md-h { margin: 10px 0 4px; line-height: 1.3; font-weight: 600; }
.prose-block .md-h1 { font-size: 18px; }
.prose-block .md-h2 { font-size: 16px; }
.prose-block .md-h3 { font-size: 14px; }
.prose-block .md-h4 { font-size: 13px; }
.prose-block .md-ul, .prose-block .md-ol { margin: 4px 0; padding-left: 20px; }
.prose-block .md-ul li, .prose-block .md-ol li { margin: 2px 0; }
.prose-block .md-inline-code {
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: 4px;
padding: 1px 5px;
font-family: var(--mono);
font-size: 0.92em;
}
.prose-block .md-code {
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
padding: 10px 12px;
margin: 6px 0;
overflow-x: auto;
font-size: 12px;
line-height: 1.5;
}
.prose-block .md-code code { font-family: var(--mono); }
.prose-block .md-link { color: var(--accent); text-decoration: underline; }
.prose-block .md-hr {
border: none;
border-top: 1px solid var(--border);
margin: 10px 0;
}
.op-waiting {
font-size: 12px;
color: var(--text-muted);
font-style: italic;
}
/* Thinking blocks */
.thinking-block {
background: rgba(108, 58, 166, 0.04);
border: 1px solid rgba(108, 58, 166, 0.16);
border-radius: var(--radius-sm);
}
.thinking-toggle {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 7px 12px;
background: transparent;
border: none;
text-align: left;
font-size: 12px;
color: var(--text);
border-radius: var(--radius-sm);
}
.thinking-toggle:hover { background: rgba(108, 58, 166, 0.05); border-color: transparent; }
.thinking-icon { color: var(--purple); }
.thinking-label { font-weight: 500; }
.thinking-preview {
flex: 1;
color: var(--text-muted);
font-style: italic;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.thinking-chev { color: var(--text-muted); font-size: 10px; }
.thinking-body {
margin: 0;
padding: 0 14px 12px 14px;
font-family: var(--mono);
font-size: 11px;
line-height: 1.55;
color: var(--text-muted);
white-space: pre-wrap;
overflow-wrap: anywhere;
}
/* Status pills */
.status-pill {
display: inline-flex;
align-self: flex-start;
align-items: center;
gap: 6px;
padding: 3px 12px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-pill);
font-size: 11.5px;
color: var(--text-muted);
}
.status-label { letter-spacing: 0.02em; }
.status-detail { color: var(--text); }
/* Grouped tool / action card — the collapsible pill from screenshot 9 */
.action-card {
display: flex;
flex-direction: column;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-panel);
overflow: hidden;
}
.action-card-toggle {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 8px 12px;
background: transparent;
border: none;
text-align: left;
font-size: 12.5px;
color: var(--text);
cursor: pointer;
border-radius: var(--radius);
}
.action-card-toggle:hover { background: var(--bg-subtle); border-color: transparent; }
.action-card-toggle .ico {
width: 20px; height: 20px;
display: inline-flex;
align-items: center;
justify-content: center;
border-radius: 4px;
background: var(--bg-subtle);
color: var(--text-muted);
font-size: 12px;
font-family: var(--mono);
flex-shrink: 0;
}
.action-card-toggle .summary { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.action-card-toggle .summary strong { font-weight: 500; }
.action-card-toggle .chev { color: var(--text-faint); font-size: 10px; flex-shrink: 0; }
.action-card-toggle.running .ico { animation: pulse 1.6s ease-in-out infinite; background: var(--purple-bg); color: var(--purple); }
.action-card-body {
padding: 0 12px 10px;
display: flex;
flex-direction: column;
gap: 6px;
border-top: 1px solid var(--border-soft);
}
.action-card-body > .op-card { border-color: transparent; box-shadow: none; padding: 4px 0; }
.action-card-body > .op-card .op-card-head { padding: 6px 0; }
/* Tool / operation cards — single, ungrouped */
.op-card {
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-panel);
overflow: hidden;
box-shadow: var(--shadow-xs);
min-width: 0;
max-width: 100%;
}
.op-card-head {
display: flex;
align-items: center;
gap: 8px;
padding: 8px 12px;
font-size: 12.5px;
flex-wrap: wrap;
}
.op-icon {
width: 22px;
height: 22px;
border-radius: 6px;
background: var(--bg-subtle);
display: inline-flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
font-size: 12px;
font-family: var(--mono);
flex-shrink: 0;
}
.op-icon-write { background: var(--green-bg); color: var(--green); }
.op-icon-edit { background: var(--amber-bg); color: var(--amber); }
.op-icon-read { background: var(--blue-bg); color: var(--blue); }
.op-title { font-weight: 500; }
.op-meta { color: var(--text-muted); font-size: 11.5px; }
.op-desc { font-style: italic; }
.op-path {
background: var(--bg-subtle);
padding: 1px 6px;
border-radius: 4px;
font-size: 11px;
font-family: var(--mono);
color: var(--text);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
max-width: min(220px, 100%);
}
.op-status {
margin-left: auto;
font-size: 10.5px;
padding: 2px 9px;
border-radius: var(--radius-pill);
letter-spacing: 0.02em;
border: 1px solid var(--border);
color: var(--text-muted);
background: var(--bg-subtle);
}
.op-status-running {
border-color: var(--purple-border);
background: var(--purple-bg);
color: var(--purple);
animation: pulse 1.6s ease-in-out infinite;
}
.op-status-ok { border-color: var(--green-border); background: var(--green-bg); color: var(--green); }
.op-status-error { border-color: var(--red-border); background: var(--red-bg); color: var(--red); }
.op-toggle {
font-size: 10.5px;
padding: 2px 8px;
border: 1px solid var(--border);
border-radius: var(--radius-pill);
background: transparent;
color: var(--text-muted);
}
.op-open {
font-size: 10.5px;
padding: 2px 9px;
border: 1px solid var(--border);
border-radius: var(--radius-pill);
background: transparent;
color: var(--text);
cursor: pointer;
}
.op-open:hover {
background: var(--bg-subtle);
border-color: var(--accent);
color: var(--accent);
}
.produced-files {
margin-top: 4px;
padding: 12px 14px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius);
}
.produced-files-label {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
margin-bottom: 8px;
font-weight: 600;
}
.produced-files-list { display: flex; flex-direction: column; gap: 4px; }
.produced-file {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
border-radius: 6px;
background: var(--bg-panel);
border: 1px solid var(--border);
font-size: 12px;
}
.produced-file-icon { width: 22px; text-align: center; color: var(--text-muted); }
.produced-file-name {
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-family: var(--mono);
}
.produced-file-size {
font-size: 10.5px;
color: var(--text-muted);
font-variant-numeric: tabular-nums;
}
.produced-file-actions { display: flex; gap: 6px; }
.produced-file-actions .ghost,
.produced-file-actions .ghost-link {
font-size: 11px;
padding: 3px 9px;
}
.op-bash .op-command,
.op-bash .op-output {
margin: 0;
padding: 8px 12px;
background: #1c1b1a;
color: #f0eee9;
font-family: var(--mono);
font-size: 11px;
line-height: 1.55;
white-space: pre-wrap;
overflow-wrap: anywhere;
max-height: 220px;
overflow-y: auto;
}
.op-bash .op-output { background: #2a2926; }
.op-todo .todo-list {
list-style: none;
margin: 0;
padding: 6px 8px 10px;
display: flex;
flex-direction: column;
gap: 1px;
font-size: 12px;
}
.todo-item {
display: flex;
align-items: flex-start;
gap: 10px;
padding: 5px 8px;
line-height: 1.45;
border-radius: var(--radius-sm);
border: 1px solid transparent;
transition: background-color 120ms ease, border-color 120ms ease;
}
.todo-check {
width: 16px;
flex-shrink: 0;
color: var(--text-soft);
font-family: var(--mono);
text-align: center;
line-height: 1.45;
}
.todo-text { color: var(--text); }
/* Pending — quietly waiting */
.todo-pending .todo-check { color: var(--text-faint); }
.todo-pending .todo-text { color: var(--text-muted); }
/* In progress — the only row that should pop */
.todo-in_progress {
background: color-mix(in srgb, var(--accent) 10%, var(--bg-panel));
border-color: color-mix(in srgb, var(--accent) 28%, transparent);
}
.todo-in_progress .todo-check { color: var(--accent); }
.todo-in_progress .todo-text { color: var(--text-strong); font-weight: 600; }
/* Completed — settled, but still readable */
.todo-completed .todo-check { color: var(--green); }
.todo-completed .todo-text {
text-decoration: line-through;
text-decoration-color: color-mix(in srgb, var(--text-muted) 60%, transparent);
color: var(--text-muted);
}
/* Composer extras */
.composer.drag-active {
outline: 2px dashed var(--accent);
outline-offset: -4px;
}
/* Present / Share menus */
.present-wrap { position: relative; display: inline-block; }
.present-trigger .caret {
margin-left: 4px;
font-size: 10px;
opacity: 0.7;
}
.present-menu {
position: absolute;
top: calc(100% + 6px);
right: 0;
z-index: 60;
min-width: 168px;
padding: 4px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
display: flex;
flex-direction: column;
}
.present-menu button {
background: transparent;
border: none;
padding: 8px 10px;
font-size: 12px;
text-align: left;
border-radius: 6px;
cursor: pointer;
display: flex;
align-items: center;
gap: 10px;
color: var(--text);
}
.present-menu button:hover { background: var(--bg-subtle); border-color: transparent; }
.present-icon {
display: inline-flex;
width: 14px;
justify-content: center;
color: var(--text-muted);
font-size: 12px;
}
.share-menu { position: relative; display: inline-block; }
.share-menu-popover {
position: absolute;
top: calc(100% + 6px);
right: 0;
z-index: 50;
min-width: 240px;
padding: 4px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
display: flex;
flex-direction: column;
}
.share-menu-item {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
font-size: 12.5px;
text-align: left;
background: transparent;
border: none;
border-radius: 6px;
cursor: pointer;
color: var(--text);
}
.share-menu-item:hover:not(:disabled) {
background: var(--bg-subtle);
border-color: transparent;
}
.share-menu-item:disabled { opacity: 0.45; cursor: not-allowed; }
.share-menu-icon { flex: 0 0 auto; width: 18px; text-align: center; font-size: 13px; }
.share-menu-divider { height: 1px; background: var(--border); margin: 4px 6px; }
.button-like {
display: inline-flex;
align-items: center;
justify-content: center;
min-height: 36px;
padding: 0 14px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-panel);
color: var(--text);
text-decoration: none;
cursor: pointer;
}
.button-like:disabled {
opacity: 0.5;
cursor: not-allowed;
}
.deploy-modal {
width: min(760px, calc(100vw - 32px));
max-height: calc(100vh - 32px);
overflow: auto;
}
.deploy-form {
display: flex;
flex-direction: column;
gap: 14px;
margin-top: 18px;
}
.field-label-row {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 16px;
}
.field-label-row a {
color: var(--accent);
font-size: 13px;
white-space: nowrap;
}
.field-label-group {
display: inline-flex;
align-items: center;
gap: 8px;
flex-wrap: wrap;
}
.field-label-link {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 11.5px;
color: var(--text-muted);
text-decoration: none;
white-space: nowrap;
transition: color 120ms ease;
}
.field-label-link:hover {
color: var(--accent);
}
.field-label-link svg {
opacity: 0.75;
transition: transform 120ms ease, opacity 120ms ease;
}
.field-label-link:hover svg {
opacity: 1;
transform: translate(1px, -1px);
}
.field-status-badge {
display: inline-flex;
align-items: center;
font-size: 10.5px;
font-weight: 600;
letter-spacing: 0.02em;
padding: 2px 7px;
border-radius: var(--radius-pill);
color: #137a3d;
background: color-mix(in srgb, #1f9d55 10%, transparent);
border: 1px solid color-mix(in srgb, #1f9d55 28%, var(--border));
font-variant-numeric: tabular-nums;
}
.deploy-form input {
width: 100%;
min-height: 44px;
border: 1px solid var(--border);
border-radius: var(--radius);
padding: 0 12px;
background: var(--bg-panel);
color: var(--text);
font: inherit;
}
.deploy-config-actions {
display: flex;
justify-content: flex-end;
}
.deploy-field-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 12px;
}
.deploy-field-grid label {
display: flex;
flex-direction: column;
gap: 6px;
}
.deploy-error {
margin: 0;
color: var(--red);
}
.deploy-result {
display: flex;
flex-direction: column;
gap: 10px;
padding: 14px;
border-radius: var(--radius-lg);
}
.deploy-result.ready {
border: 1px solid color-mix(in srgb, var(--green) 35%, var(--border));
background: color-mix(in srgb, var(--green) 10%, var(--bg-panel));
}
.deploy-result.delayed {
border: 1px solid color-mix(in srgb, #b7791f 42%, var(--border));
background: color-mix(in srgb, #b7791f 10%, var(--bg-panel));
}
.deploy-result.protected {
border: 1px solid color-mix(in srgb, #c96442 48%, var(--border));
background: color-mix(in srgb, #c96442 10%, var(--bg-panel));
}
.deploy-result-label {
font-size: 12px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
color: var(--green);
}
.deploy-result.delayed .deploy-result-label {
color: #9a5b12;
}
.deploy-result.protected .deploy-result-label {
color: #a34828;
}
.deploy-result-message {
margin: 0;
color: var(--muted);
}
.deploy-result a {
overflow-wrap: anywhere;
}
.deploy-result-actions {
display: flex;
justify-content: flex-end;
align-items: center;
gap: 10px;
}
.ghost-link.disabled,
.ghost-link[aria-disabled='true'] {
opacity: 0.45;
pointer-events: none;
cursor: not-allowed;
}
.present-overlay {
position: fixed;
inset: 0;
z-index: 1000;
background: black;
display: flex;
}
.present-overlay iframe {
flex: 1;
width: 100%;
height: 100%;
border: none;
background: white;
}
.present-exit {
position: absolute;
top: 12px;
right: 12px;
z-index: 1001;
padding: 6px 12px;
font-size: 12px;
background: rgba(255, 255, 255, 0.92);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
cursor: pointer;
}
.present-exit:hover { background: white; }
/* Picker (legacy in some surfaces) */
.picker {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 2px 6px 2px 10px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
}
.picker-label {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
}
.picker select {
border: none;
background: transparent;
padding: 4px 6px;
width: auto;
min-width: 120px;
box-shadow: none;
}
.picker select:focus { outline: none; box-shadow: none; }
.picker.agent-picker select { min-width: 140px; }
.picker.agent-picker .icon-btn {
padding: 2px 8px;
background: transparent;
border: none;
}
/* Preview pane (legacy single-iframe path; kept for fallbacks) */
.preview {
display: flex;
flex-direction: column;
background: var(--bg-subtle);
min-height: 0;
}
.preview-header {
padding: 8px 12px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
display: flex;
justify-content: space-between;
align-items: center;
font-size: 12px;
color: var(--text-muted);
}
.preview-title {
display: flex; align-items: center; gap: 10px; min-width: 0;
}
.preview-actions { display: flex; gap: 8px; align-items: center; }
.preview-actions .muted { font-size: 11px; }
.preview-actions button { padding: 4px 10px; font-size: 12px; }
.preview-body { flex: 1; min-height: 0; position: relative; }
.preview-body iframe {
width: 100%; height: 100%; border: none; background: white;
}
.preview-empty {
display: flex; align-items: center; justify-content: center;
height: 100%;
color: var(--text-muted);
padding: 24px;
text-align: center;
font-size: 13px;
}
/* ============================================================
Merged from main — persistence-era additions: editable project
title, conversations dropdown, examples filters + preview modal,
question form, design-system modal, system reminder collapse,
operations todo card.
============================================================ */
/* Editable project title (inline rename in topbar) */
.topbar-title .title.editable,
.app-project-title .title.editable {
outline: none;
border-radius: 4px;
padding: 1px 4px;
margin: -1px -4px;
}
.topbar-title .title.editable:focus,
.app-project-title .title.editable:focus {
background: var(--bg-subtle);
box-shadow: 0 0 0 1px var(--accent);
}
/* Conversations dropdown — pill in the project topbar */
.conv-pill {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 10px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-panel);
font: inherit;
font-size: 12px;
color: inherit;
cursor: pointer;
user-select: none;
max-width: 220px;
}
.conv-pill:hover { background: var(--bg-subtle); }
.conv-pill.open { background: var(--bg-subtle); border-color: var(--accent); }
.conv-pill-icon { font-size: 13px; line-height: 1; }
.conv-pill-label {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.conv-pill-count {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 18px;
height: 18px;
padding: 0 6px;
border-radius: 9px;
background: var(--bg-subtle);
color: var(--text-muted);
font-size: 10px;
}
.conv-menu {
position: fixed;
width: 320px;
max-height: 420px;
overflow-y: auto;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12);
z-index: 200;
padding: 8px;
}
.conv-menu-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px 6px 8px;
border-bottom: 1px solid var(--border);
margin-bottom: 6px;
font-size: 11px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.05em;
}
.conv-add-btn { padding: 2px 8px; font-size: 11px; }
.conv-menu-empty {
padding: 16px 8px;
font-size: 12px;
color: var(--text-muted);
text-align: center;
}
.conv-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.conv-item {
display: flex;
align-items: stretch;
gap: 4px;
border-radius: 6px;
}
.conv-item.active { background: var(--bg-subtle); }
.conv-item-button {
flex: 1;
display: flex;
flex-direction: column;
gap: 2px;
padding: 6px 8px;
border: none;
background: transparent;
text-align: left;
border-radius: 6px;
cursor: pointer;
}
.conv-item-button:hover { background: var(--bg-subtle); }
.conv-item-name {
font-size: 12px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.conv-item-meta {
font-size: 10px;
color: var(--text-muted);
}
.conv-item-del {
border: none;
background: transparent;
color: var(--text-muted);
font-size: 16px;
width: 24px;
cursor: pointer;
border-radius: 6px;
}
.conv-item-del:hover { background: var(--bg-subtle); color: var(--text); }
.conv-rename-input {
flex: 1;
border: 1px solid var(--accent);
border-radius: 6px;
background: var(--bg-panel);
padding: 6px 8px;
font: inherit;
font-size: 12px;
}
/* Collapsible system-reminder block in chat */
.system-reminder-block {
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius);
margin: 6px 0;
}
.system-reminder-toggle {
display: flex;
align-items: center;
gap: 8px;
width: 100%;
padding: 6px 10px;
background: transparent;
border: none;
text-align: left;
font-size: 12px;
color: var(--text-muted);
}
.system-reminder-toggle:hover { background: rgba(0, 0, 0, 0.03); }
.system-reminder-icon { color: var(--text-muted); }
.system-reminder-label { font-weight: 500; color: var(--text); }
.system-reminder-preview {
flex: 1;
color: var(--text-muted);
font-style: italic;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.system-reminder-chev { color: var(--text-muted); font-size: 10px; }
.system-reminder-body {
margin: 0;
padding: 0 12px 10px 12px;
font-family: var(--mono);
font-size: 11px;
line-height: 1.5;
color: var(--text-muted);
white-space: pre-wrap;
overflow-wrap: anywhere;
}
/* Waiting-on-input pill (richer than the simple italic version above). */
.op-waiting {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 8px;
padding: 8px 12px;
border: 1px solid var(--border);
border-radius: var(--radius);
background: var(--bg-subtle);
font-size: 12px;
color: var(--text-muted);
font-style: normal;
}
.op-waiting-dot {
width: 8px;
height: 8px;
border-radius: 999px;
background: var(--accent);
flex-shrink: 0;
animation: pulse 1.4s ease-in-out infinite;
}
.op-waiting-label {
font-weight: 500;
color: var(--text);
}
.op-waiting-detail {
font-family: var(--mono);
font-size: 11px;
background: var(--bg-panel);
padding: 1px 6px;
border-radius: 4px;
color: var(--text-muted);
}
.op-waiting-hint {
flex-basis: 100%;
font-size: 11px;
color: var(--text-soft);
font-style: italic;
}
/* op-todo card variant (the .op-todo .todo-list rule already exists above) */
.op-todo {
border-color: var(--accent-soft);
background: linear-gradient(180deg, var(--accent-tint) 0%, var(--bg-panel) 60%);
}
.op-todo .op-card-head {
border-bottom: 1px solid color-mix(in srgb, var(--accent-soft) 70%, transparent);
background: transparent;
}
.op-todo .op-icon {
background: var(--accent-soft);
color: var(--accent);
}
.op-todo .op-title {
letter-spacing: 0.02em;
text-transform: uppercase;
font-size: 11px;
color: var(--text-strong);
}
.op-todo .op-meta {
margin-left: auto;
font-variant-numeric: tabular-nums;
font-size: 11px;
color: var(--text-strong);
}
/* Question form — interactive form a planning agent can post into chat */
.question-form {
margin: 8px 0;
border: 1px solid var(--border);
border-radius: var(--radius-lg);
background: var(--bg-panel);
box-shadow: var(--shadow-md);
overflow: hidden;
}
.question-form-locked {
background: var(--bg-subtle);
box-shadow: none;
opacity: 0.92;
}
.question-form-head {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 14px;
border-bottom: 1px solid var(--border);
background: linear-gradient(180deg, var(--accent-tint) 0%, var(--bg-panel) 100%);
}
.question-form-locked .question-form-head {
background: var(--bg-subtle);
}
.question-form-icon {
width: 28px;
height: 28px;
border-radius: 999px;
background: var(--accent);
color: white;
font-weight: 600;
font-size: 14px;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.question-form-titles {
flex: 1;
min-width: 0;
}
.question-form-title {
font-size: 14px;
font-weight: 600;
letter-spacing: -0.01em;
color: var(--text);
}
.question-form-desc {
margin-top: 2px;
font-size: 12px;
color: var(--text-muted);
line-height: 1.45;
}
.question-form-pill {
font-size: 10px;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 3px 8px;
border-radius: 999px;
background: var(--bg-panel);
border: 1px solid var(--border);
color: var(--text-muted);
}
.question-form-body {
display: flex;
flex-direction: column;
gap: 14px;
padding: 14px;
}
.qf-field { display: flex; flex-direction: column; gap: 6px; }
.qf-label {
font-size: 12px;
font-weight: 500;
color: var(--text);
display: flex;
align-items: center;
gap: 4px;
}
.qf-required { color: var(--accent); }
.qf-help { font-size: 11px; color: var(--text-muted); margin-top: -2px; }
.qf-options {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.qf-chip {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
border: 1px solid var(--border);
border-radius: 999px;
background: var(--bg-panel);
font-size: 12px;
cursor: pointer;
transition: border-color 120ms ease, background 120ms ease, color 120ms ease;
}
.qf-chip input { width: auto; margin: 0; display: none; }
.qf-chip:hover { border-color: var(--border-strong); }
.qf-chip-disabled {
cursor: not-allowed;
opacity: 0.48;
}
.qf-chip-disabled:hover { border-color: var(--border); }
.qf-chip-on {
border-color: var(--accent);
background: var(--accent-soft);
color: var(--accent-hover);
font-weight: 500;
}
.question-form-locked .qf-chip { cursor: not-allowed; }
.qf-input,
.qf-select,
.qf-textarea {
font-size: 13px;
}
.question-form-foot {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 14px;
border-top: 1px solid var(--border);
background: var(--bg-subtle);
}
.qf-hint,
.qf-locked-note {
flex: 1;
font-size: 11px;
color: var(--text-muted);
line-height: 1.4;
}
/* Direction-cards picker — used by the second discovery form when the user
selects "Pick a direction for me". Each card carries a palette swatch
row, a serif/sans type sample, a mood blurb, and a real-world refs
line so the user can scan visually instead of squinting at radio labels. */
.qf-direction-cards {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 10px;
margin-top: 4px;
}
.qf-card {
position: relative;
display: flex;
flex-direction: column;
gap: 10px;
padding: 14px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 10px;
cursor: pointer;
transition:
border-color 0.12s ease,
background 0.12s ease,
transform 0.06s ease;
}
.qf-card input { display: none; }
.qf-card:hover { border-color: var(--border-strong); }
.qf-card:active { transform: translateY(1px); }
.qf-card-on {
border-color: var(--accent, #c96442);
background: color-mix(in oklch, var(--accent, #c96442) 4%, var(--bg));
box-shadow: 0 0 0 1px var(--accent, #c96442) inset;
}
.qf-card-disabled { cursor: not-allowed; opacity: 0.6; }
.qf-card-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
}
.qf-card-title {
font-size: 13px;
font-weight: 600;
letter-spacing: -0.005em;
color: var(--text);
line-height: 1.3;
}
.qf-card-pill {
font-family: ui-monospace, 'JetBrains Mono', monospace;
font-size: 9px;
letter-spacing: 0.06em;
text-transform: uppercase;
padding: 2px 6px;
background: var(--accent, #c96442);
color: #fff;
border-radius: 999px;
flex-shrink: 0;
}
.qf-card-swatches {
display: flex;
gap: 4px;
height: 18px;
}
.qf-card-swatch {
flex: 1;
border-radius: 3px;
border: 1px solid rgba(0, 0, 0, 0.08);
min-width: 0;
}
.qf-card-types {
display: flex;
align-items: baseline;
gap: 12px;
padding: 6px 0;
border-top: 1px solid var(--border);
border-bottom: 1px solid var(--border);
}
.qf-card-type-display {
font-size: 28px;
line-height: 1;
letter-spacing: -0.02em;
color: var(--text);
flex-shrink: 0;
}
.qf-card-type-body {
font-size: 12px;
color: var(--text-muted);
line-height: 1.3;
letter-spacing: -0.005em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.qf-card-mood {
margin: 0;
font-size: 12px;
line-height: 1.45;
color: var(--text-muted);
}
.qf-card-refs {
margin: 0;
font-size: 11px;
color: var(--text-muted);
line-height: 1.4;
}
.qf-card-refs-label {
font-family: ui-monospace, 'JetBrains Mono', monospace;
font-size: 10px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--text-muted);
opacity: 0.7;
}
/* Design-system preview modal */
.ds-modal-backdrop {
position: fixed;
inset: 0;
z-index: 900;
background: rgba(28, 27, 26, 0.42);
backdrop-filter: blur(2px);
display: flex;
align-items: stretch;
justify-content: center;
padding: 32px;
}
.ds-modal {
width: 100%;
max-width: 1320px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
display: flex;
flex-direction: column;
overflow: hidden;
min-height: 0;
}
.ds-modal-fullscreen {
max-width: none;
border-radius: 0;
}
.ds-modal-header {
display: grid;
grid-template-columns: 1fr auto 1fr;
align-items: center;
gap: 16px;
padding: 14px 18px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
}
.ds-modal-title-block {
min-width: 0;
display: flex;
flex-direction: column;
gap: 2px;
}
.ds-modal-title {
font-size: 15px;
font-weight: 600;
letter-spacing: -0.01em;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.ds-modal-subtitle {
font-size: 12px;
color: var(--text-muted);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 60ch;
}
.ds-modal-tabs {
display: inline-flex;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: 999px;
padding: 3px;
gap: 2px;
}
.ds-modal-tab {
background: transparent;
border: none;
border-radius: 999px;
padding: 6px 16px;
font-size: 12.5px;
font-weight: 500;
color: var(--text-muted);
cursor: pointer;
}
.ds-modal-tab:hover { color: var(--text); }
.ds-modal-tab.active {
background: var(--bg-panel);
color: var(--text);
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
}
.ds-modal-actions {
display: flex;
align-items: center;
gap: 8px;
justify-content: flex-end;
}
.ds-modal-stage {
flex: 1;
min-height: 0;
background: white;
position: relative;
display: flex;
align-items: stretch;
}
.ds-modal-stage-iframe {
flex: 1;
min-width: 0;
position: relative;
overflow: hidden;
background: white;
}
.ds-modal-stage-iframe-scaler {
position: absolute;
top: 0;
left: 0;
transform-origin: top left;
background: white;
/* Prevent the GPU layer from blurring the scaled iframe on Retina. */
will-change: transform;
}
.ds-modal-stage-iframe-scaler iframe {
width: 100%;
height: 100%;
border: none;
display: block;
background: white;
}
.ds-modal-stage.has-sidebar .ds-modal-stage-iframe {
flex: 1 1 60%;
}
.ds-modal-sidebar {
position: relative;
flex: 1 1 40%;
min-width: 320px;
max-width: 560px;
border-left: 1px solid var(--border);
background: var(--bg-panel);
overflow: auto;
display: flex;
flex-direction: column;
}
.ds-modal-stage-handle {
position: absolute;
top: 50%;
width: 18px;
height: 56px;
transform: translateY(-50%);
background: var(--bg-panel);
border: 1px solid var(--border);
color: var(--text-muted);
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
line-height: 1;
padding: 0;
z-index: 3;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);
transition: color 120ms ease, background 120ms ease;
}
.ds-modal-stage-handle:hover { color: var(--text); background: var(--bg-subtle); }
.ds-modal-stage-handle.is-expand {
right: 0;
border-right: none;
border-radius: 8px 0 0 8px;
}
.ds-modal-stage-handle.is-collapse {
left: 0;
border-left: none;
border-radius: 0 8px 8px 0;
}
.ds-modal-fullscreen .ds-modal-stage:fullscreen .ds-modal-stage-iframe-scaler,
.ds-modal-stage:fullscreen .ds-modal-stage-iframe-scaler {
height: 100vh;
}
.ds-modal-empty {
position: absolute;
inset: 0;
display: flex;
align-items: center;
justify-content: center;
color: var(--text-muted);
font-size: 13px;
}
.ds-modal-actions .ghost.is-active {
background: var(--accent-tint);
color: var(--accent);
border-color: var(--accent);
}
/* DESIGN.md side panel — monospace source view with light syntax tints,
echoing the styles.refero.design "compact" markdown source pane. */
.design-spec-empty {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
padding: 24px;
color: var(--text-muted);
font-size: 12px;
}
.design-spec-pre {
margin: 0;
padding: 16px 18px;
font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, "Liberation Mono", monospace;
font-size: 12px;
line-height: 1.6;
/* Wrap long lines instead of forcing the side pane to scroll horizontally —
DESIGN.md prose can have 200+ char paragraphs that otherwise produce a
scrollbar inside the modal. `overflow-wrap: anywhere` keeps long
hyphenated tokens (URLs, file paths) from blowing out the column. */
white-space: pre-wrap;
overflow-wrap: anywhere;
word-break: break-word;
overflow-y: auto;
overflow-x: hidden;
color: var(--text);
background: var(--bg-panel);
flex: 1;
}
.design-spec-pre code { font: inherit; color: inherit; background: transparent; }
.design-spec-line { display: inline; }
.design-spec-line.is-h1 { color: #2563eb; font-weight: 700; }
.design-spec-line.is-h2 { color: #0891b2; font-weight: 700; }
.design-spec-line.is-h3 { color: #0d9488; font-weight: 600; }
.design-spec-line.is-h4 { color: #16a34a; font-weight: 600; }
.design-spec-line.is-quote { color: #6b7280; font-style: italic; }
.design-spec-line.is-list { color: var(--text); }
.design-spec-line.is-table { color: #7c3aed; }
.design-spec-line.is-fence { color: #dc2626; }
.design-spec-line.is-blank { color: var(--text-muted); }
.md-tk-bold { font-weight: 700; color: var(--text); }
.md-tk-em { font-style: italic; color: var(--text); }
.md-tk-code {
background: var(--bg-subtle);
padding: 0 4px;
border-radius: 3px;
color: #0f766e;
}
.md-tk-color {
display: inline-flex;
align-items: center;
gap: 4px;
color: #be185d;
}
.md-tk-color-swatch {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 2px;
border: 1px solid rgba(0, 0, 0, 0.12);
vertical-align: middle;
}
@media (max-width: 760px) {
.ds-modal-backdrop { padding: 0; }
.ds-modal { border-radius: 0; }
.ds-modal-header { grid-template-columns: 1fr; gap: 8px; }
.ds-modal-actions { justify-content: flex-start; flex-wrap: wrap; }
.ds-modal-stage { flex-direction: column; }
.ds-modal-stage.has-sidebar .ds-modal-stage-iframe { flex: 1 1 50%; }
.ds-modal-sidebar {
border-left: none;
border-top: 1px solid var(--border);
flex: 1 1 50%;
min-width: 0;
max-width: none;
}
/* On stacked layout the side handles (which assume horizontal split)
would float over content awkwardly — fall back to the header toggle. */
.ds-modal-stage-handle { display: none; }
}
/* Examples gallery toolbar — filter pills + richer card metadata */
.examples-toolbar {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 8px;
}
.examples-search {
position: relative;
width: min(360px, 100%);
}
.examples-search input {
width: 100%;
padding: 7px 12px 7px 32px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: 8px;
font-size: 13px;
color: var(--text);
}
.examples-search input::placeholder { color: var(--text-faint); }
.examples-search input:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.examples-search .search-icon {
position: absolute;
left: 10px;
top: 50%;
transform: translateY(-50%);
color: var(--text-faint);
pointer-events: none;
display: inline-flex;
align-items: center;
}
.examples-filter-row {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
}
.examples-filter-label {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
margin-right: 6px;
font-weight: 500;
}
.filter-pill {
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: 999px;
padding: 5px 12px;
font-size: 12px;
color: var(--text-muted);
cursor: pointer;
display: inline-flex;
gap: 6px;
align-items: center;
}
.filter-pill:hover { border-color: var(--border-strong); color: var(--text); }
.filter-pill.active {
background: var(--accent);
border-color: var(--accent);
color: white;
}
.filter-pill-count {
font-size: 11px;
opacity: 0.7;
}
.example-card-actions {
display: flex;
gap: 8px;
align-items: center;
flex-wrap: wrap;
}
.example-tags {
display: flex;
gap: 6px;
flex-wrap: wrap;
margin-top: 2px;
}
/* Tag variants — keep the worktree base .example-tag style; these add
color-coded variants for mode/platform pills. */
.example-tag.platform-mobile { color: var(--accent); border-color: var(--accent-soft); background: var(--accent-soft); }
.example-tag.mode-deck { color: var(--accent); border-color: var(--accent-soft); background: var(--accent-soft); }
/* Example preview hover affordance + click-through overlay */
.example-preview {
cursor: zoom-in;
transition: border-color 0.15s, box-shadow 0.15s;
}
.example-preview:hover {
border-color: var(--accent);
box-shadow: 0 6px 18px rgba(201, 100, 66, 0.10);
}
.example-preview:focus-visible {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 3px var(--accent-soft);
}
.example-preview-overlay {
position: absolute;
bottom: 10px;
right: 10px;
padding: 5px 12px;
font-size: 11.5px;
font-weight: 500;
color: white;
background: rgba(28, 27, 26, 0.78);
border-radius: 999px;
opacity: 0;
transition: opacity 0.15s;
pointer-events: none;
letter-spacing: 0.02em;
}
.example-preview:hover .example-preview-overlay,
.example-preview:focus-visible .example-preview-overlay { opacity: 1; }
/* ============================================================
Loading primitives — spinner, skeletons, shimmer
============================================================ */
@keyframes icon-spin { to { transform: rotate(360deg); } }
@keyframes shimmer {
0% { background-position: -400px 0; }
100% { background-position: 400px 0; }
}
.icon-spin { animation: icon-spin 0.9s linear infinite; transform-origin: center; }
.loading-spinner {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--text-muted);
}
.loading-spinner-label { font-size: 12px; }
.skeleton-block,
.skeleton-shimmer {
display: inline-block;
background-color: var(--bg-subtle);
background-image: linear-gradient(
90deg,
var(--bg-subtle) 0%,
var(--bg-muted) 50%,
var(--bg-subtle) 100%
);
background-size: 800px 100%;
animation: shimmer 1.4s linear infinite;
}
.skeleton-block + .skeleton-block { margin-top: 6px; }
.design-card-skeleton { cursor: default; pointer-events: none; }
.design-card-skeleton .design-card-thumb { background: none; }
.design-card-skeleton .design-card-thumb::before,
.design-card-skeleton .design-card-thumb::after { display: none; }
.design-card-skeleton .design-card-thumb {
background-image: linear-gradient(
90deg,
var(--bg-subtle) 0%,
var(--bg-muted) 50%,
var(--bg-subtle) 100%
);
background-size: 800px 100%;
animation: shimmer 1.4s linear infinite;
}
.centered-loader {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 10px;
padding: 48px 12px;
color: var(--text-muted);
}
.centered-loader-label { font-size: 12.5px; letter-spacing: 0.01em; }
/* ============================================================
Resizable entry sidebar
============================================================ */
.entry {
/* The sidebar width is driven by an inline style fed from local state,
with sensible bounds enforced in JS. */
}
.entry-side {
position: relative;
min-width: 280px;
max-width: 560px;
}
.entry-side-resizer {
position: absolute;
top: 0;
right: -3px;
width: 6px;
height: 100%;
cursor: col-resize;
z-index: 5;
background: transparent;
border: 0;
padding: 0;
transition: background-color 120ms ease;
}
.entry-side-resizer:hover,
.entry-side-resizer.dragging { background: var(--accent-soft); }
body.entry-resizing { cursor: col-resize; user-select: none; }
/* Branded header — title + research-preview pill on a single line, with
the "by …" subtitle underneath. */
.entry-brand-title-row {
flex-wrap: wrap;
row-gap: 4px;
}
/* ============================================================
Composer Import popover (coming-soon menu)
============================================================ */
.composer-import-wrap { position: relative; }
.composer-import-menu {
position: absolute;
bottom: calc(100% + 6px);
left: 0;
min-width: 240px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
padding: 6px;
display: flex;
flex-direction: column;
gap: 2px;
z-index: 30;
animation: pop-in 180ms cubic-bezier(0.21, 1.02, 0.73, 1);
}
.composer-import-item {
display: flex;
align-items: center;
gap: 10px;
padding: 8px 10px;
background: transparent;
border: none;
border-radius: var(--radius-sm);
color: var(--text-muted);
cursor: not-allowed;
font-size: 12.5px;
text-align: left;
width: 100%;
}
.composer-import-item:hover {
background: var(--bg-subtle);
color: var(--text);
}
.composer-import-item-label { flex: 1; }
.composer-import-item-soon {
font-size: 10px;
letter-spacing: 0.05em;
text-transform: uppercase;
color: var(--text-faint);
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-pill);
padding: 2px 6px;
}
.composer-import-item .ico {
display: inline-flex;
width: 16px;
align-items: center;
justify-content: center;
color: var(--text-muted);
}
/* ============================================================
Chat header: conversation history dropdown
============================================================ */
.chat-history-wrap { position: relative; display: inline-flex; align-items: center; }
.chat-history-wrap .icon-only { position: relative; }
.chat-history-wrap.open .icon-only { background: var(--bg-subtle); color: var(--text); }
.chat-history-badge {
position: absolute;
top: 2px;
right: 2px;
min-width: 14px;
height: 14px;
padding: 0 3px;
font-size: 9.5px;
font-weight: 600;
letter-spacing: 0;
background: var(--accent);
color: white;
border-radius: 999px;
display: inline-flex;
align-items: center;
justify-content: center;
line-height: 1;
}
.chat-history-menu {
position: absolute;
top: calc(100% + 6px);
right: 0;
width: 280px;
max-height: 360px;
display: flex;
flex-direction: column;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
z-index: 30;
overflow: hidden;
animation: pop-in 180ms cubic-bezier(0.21, 1.02, 0.73, 1);
}
.chat-history-menu-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 10px;
border-bottom: 1px solid var(--border);
background: var(--bg-panel);
}
.chat-history-menu-title {
font-size: 11px;
text-transform: uppercase;
letter-spacing: 0.06em;
color: var(--text-muted);
font-weight: 600;
}
.chat-history-new {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 8px;
font-size: 11px;
border-radius: var(--radius-pill);
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
}
.chat-history-new:hover { background: var(--bg-muted); color: var(--text); }
.chat-history-list {
display: flex;
flex-direction: column;
gap: 1px;
padding: 4px 6px 6px;
overflow-y: auto;
}
.chat-history-empty {
padding: 16px 8px;
font-size: 12px;
color: var(--text-muted);
text-align: center;
font-style: italic;
}
.chat-conv-item {
display: flex;
align-items: center;
gap: 8px;
padding: 6px 8px;
border-radius: var(--radius-sm);
background: transparent;
border: 1px solid transparent;
color: var(--text);
font-size: 12.5px;
text-align: left;
cursor: pointer;
width: 100%;
}
.chat-conv-item:hover { background: var(--bg-subtle); }
.chat-conv-item.active {
background: var(--accent-tint);
border-color: var(--accent-soft);
color: var(--text-strong);
}
.chat-conv-item-name {
flex: 1;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.chat-conv-item-meta {
font-size: 10.5px;
color: var(--text-faint);
font-variant-numeric: tabular-nums;
}
.chat-conv-item-del {
width: 22px;
height: 22px;
padding: 0;
border: none;
background: transparent;
color: var(--text-faint);
border-radius: 4px;
display: inline-flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: opacity 120ms ease, background-color 120ms ease, color 120ms ease;
}
.chat-conv-item:hover .chat-conv-item-del { opacity: 1; }
.chat-conv-item-del:hover { background: var(--red-bg); color: var(--red); }
/* ============================================================
Scroll-to-bottom button (chat)
============================================================ */
.chat-log-wrap { position: relative; flex: 1; min-height: 0; min-width: 0; display: flex; }
.chat-log-wrap .chat-log { flex: 1; }
.chat-jump-btn {
position: absolute;
bottom: 12px;
left: 50%;
transform: translateX(-50%);
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
border-radius: var(--radius-pill);
background: var(--bg-panel);
border: 1px solid var(--border-strong);
color: var(--text);
font-size: 12px;
box-shadow: var(--shadow-sm);
cursor: pointer;
z-index: 6;
animation: pop-in 200ms cubic-bezier(0.21, 1.02, 0.73, 1);
}
.chat-jump-btn:hover { background: var(--bg-subtle); border-color: var(--border-strong); }
/* ============================================================
Assistant message footer (bottom-of-message status pill)
============================================================ */
.assistant-footer {
display: inline-flex;
align-items: center;
gap: 8px;
margin-top: 10px;
padding: 4px 10px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-pill);
font-size: 11.5px;
color: var(--text-muted);
width: fit-content;
}
.assistant-footer .dot {
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--text-muted);
}
.assistant-footer .dot[data-active="true"] {
background: var(--accent);
animation: pulse 1.2s ease-in-out infinite;
}
.assistant-footer .assistant-label {
font-weight: 600;
color: var(--text-strong);
font-size: 11.5px;
}
.assistant-footer .assistant-stats {
font-variant-numeric: tabular-nums;
color: var(--text-muted);
}
.assistant-footer[data-unfinished="true"] {
background: var(--amber-bg);
border-color: color-mix(in srgb, var(--amber) 35%, var(--border));
}
.assistant-footer[data-unfinished="true"] .dot {
background: var(--amber);
}
.unfinished-todos {
margin-top: 10px;
width: min(520px, 100%);
padding: 10px 12px;
border: 1px solid color-mix(in srgb, var(--amber) 35%, var(--border));
border-radius: var(--radius);
background: color-mix(in srgb, var(--amber) 8%, var(--bg-panel));
color: var(--text);
}
.unfinished-todos-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
}
.unfinished-todos-title {
font-size: 12px;
font-weight: 700;
color: var(--text-strong);
}
.unfinished-todos-continue {
flex: 0 0 auto;
border: 1px solid color-mix(in srgb, var(--amber) 45%, var(--border-strong));
border-radius: var(--radius-sm);
background: var(--bg-panel);
color: var(--text-strong);
font: inherit;
font-size: 12px;
font-weight: 650;
padding: 5px 9px;
cursor: pointer;
}
.unfinished-todos-continue:hover {
background: var(--bg-subtle);
}
.unfinished-todos-list {
margin: 8px 0 0;
padding-left: 18px;
font-size: 12.5px;
color: var(--text-muted);
}
.unfinished-todos-list li + li {
margin-top: 3px;
}
.unfinished-todos-more {
margin-top: 6px;
font-size: 12px;
color: var(--text-muted);
}
/* ============================================================
Coming-soon disabled affordance for viewer toolbar buttons
============================================================ */
.viewer-action[data-coming-soon='true'] {
position: relative;
z-index: 5;
opacity: 0.55;
cursor: not-allowed;
}
.viewer-action[data-coming-soon='true']:hover { background: var(--bg-subtle); color: var(--text-muted); }
.viewer-action[data-coming-soon='true']::after {
content: 'Coming soon';
position: absolute;
bottom: calc(100% + 6px);
left: 50%;
transform: translateX(-50%);
background: rgba(17, 24, 39, 0.95);
color: white;
font-size: 10.5px;
padding: 4px 8px;
border-radius: var(--radius-sm);
white-space: nowrap;
letter-spacing: 0.03em;
pointer-events: none;
opacity: 0;
transition: opacity 120ms ease;
z-index: 10;
text-transform: uppercase;
font-weight: 600;
}
.viewer-action[data-coming-soon='true']:hover::after { opacity: 1; }
.viewer-toggle[data-coming-soon='true'] {
position: relative;
z-index: 5;
opacity: 0.55;
cursor: not-allowed;
}
.viewer-toggle[data-coming-soon='true']:hover { background: var(--bg-subtle); }
.viewer-toggle[data-coming-soon='true']::after {
content: 'Coming soon';
position: absolute;
bottom: calc(100% + 6px);
left: 50%;
transform: translateX(-50%);
background: rgba(17, 24, 39, 0.95);
color: white;
font-size: 10.5px;
padding: 4px 8px;
border-radius: var(--radius-sm);
white-space: nowrap;
letter-spacing: 0.03em;
pointer-events: none;
opacity: 0;
transition: opacity 120ms ease;
z-index: 10;
text-transform: uppercase;
font-weight: 600;
}
.viewer-toggle[data-coming-soon='true']:hover::after { opacity: 1; }
/* Polished toolbar button states — coordinate with the global system.
Hover: subtle bg + soft border so groups look intentional. */
.viewer-action,
.viewer-tab,
.viewer-toggle {
border: 1px solid transparent;
transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.viewer-action:hover:not(:disabled):not([data-coming-soon='true']),
.viewer-tab:hover { border-color: var(--border); }
.viewer-tab.active { border-color: var(--border); }
/* ============================================================
Composer — settings/upload icons consistent sizing + spacing
============================================================ */
.composer-row .icon-btn svg { display: block; }
.composer-row .icon-btn.active { background: var(--bg-subtle); color: var(--text); }
.composer-import {
display: inline-flex;
align-items: center;
gap: 6px;
}
.composer-send svg { display: block; }
/* Make the composer's leading icons share the same hit target. */
.composer-row .composer-icon-divider {
width: 1px;
height: 18px;
background: var(--border);
margin: 0 2px;
}
/* ============================================================
Deck navigation toolbar (prev / counter / next)
============================================================ */
.deck-nav {
display: inline-flex;
align-items: center;
gap: 2px;
padding: 0 6px;
margin-left: 4px;
border-left: 1px solid var(--border);
height: 28px;
}
.deck-nav-counter {
display: inline-flex;
align-items: center;
justify-content: center;
min-width: 50px;
padding: 0 6px;
font-size: 12px;
color: var(--text-muted);
font-variant-numeric: tabular-nums;
letter-spacing: 0.02em;
}
/* ============================================================
Composer rename input style for inline conversation rename.
============================================================ */
.chat-conv-rename-input {
border: 1px solid var(--accent);
border-radius: var(--radius-sm);
background: var(--bg-panel);
outline: none;
}
/* ============================================================
Prompt template gallery
============================================================ */
.prompt-templates-panel { display: flex; flex-direction: column; gap: 16px; }
.prompt-templates-count {
margin-left: auto;
color: var(--text-muted);
font-size: 12px;
}
.prompt-templates-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
gap: 14px;
}
.prompt-template-card {
display: flex;
flex-direction: column;
gap: 10px;
padding: 0;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: 10px;
overflow: hidden;
text-align: left;
cursor: pointer;
transition: border-color 0.15s ease, transform 0.15s ease;
}
.prompt-template-card:hover {
border-color: var(--border-strong);
transform: translateY(-1px);
}
.prompt-template-thumb {
position: relative;
width: 100%;
aspect-ratio: 4 / 3;
display: flex;
align-items: center;
justify-content: center;
background: var(--bg-subtle);
overflow: hidden;
}
.prompt-template-thumb img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.prompt-template-thumb-fallback {
color: var(--text-faint);
}
.prompt-template-thumb-play {
position: absolute;
right: 8px;
bottom: 8px;
background: rgba(0, 0, 0, 0.55);
color: #fff;
font-size: 10px;
width: 22px;
height: 22px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
letter-spacing: 0;
}
.prompt-template-thumb-provider {
position: absolute;
left: 8px;
top: 8px;
background: rgba(0, 0, 0, 0.62);
color: #fff;
font-size: 10px;
font-weight: 600;
padding: 3px 7px;
border-radius: 999px;
letter-spacing: 0.02em;
backdrop-filter: blur(6px);
-webkit-backdrop-filter: blur(6px);
max-width: calc(100% - 16px);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.prompt-template-thumb-provider.is-hyperframes {
background: linear-gradient(135deg, #ff5e3a 0%, #f0c14b 100%);
color: #1a1410;
}
.prompt-template-meta {
display: flex;
flex-direction: column;
gap: 4px;
padding: 0 12px 12px;
}
.prompt-template-title {
font-size: 13px;
font-weight: 600;
color: var(--text);
line-height: 1.3;
}
.prompt-template-summary {
font-size: 12px;
color: var(--text-muted);
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 3;
-webkit-box-orient: vertical;
overflow: hidden;
}
.prompt-template-tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
margin-top: 4px;
}
.prompt-template-category {
font-size: 10px;
font-weight: 600;
padding: 2px 6px;
border-radius: 4px;
background: var(--accent-tint);
color: var(--accent);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.prompt-template-tag,
.prompt-template-model {
font-size: 10px;
padding: 2px 6px;
border-radius: 4px;
background: var(--bg-subtle);
color: var(--text-muted);
}
.prompt-template-model {
font-weight: 500;
}
.prompt-template-source {
font-size: 10px;
color: var(--text-faint);
margin-top: 6px;
}
.prompt-templates-footer {
font-size: 11px;
color: var(--text-faint);
padding-top: 12px;
border-top: 1px dashed var(--border);
text-align: center;
}
.prompt-template-modal-backdrop {
position: fixed;
inset: 0;
background: rgba(15, 15, 18, 0.45);
display: flex;
align-items: center;
justify-content: center;
z-index: 1500;
padding: 24px;
}
.prompt-template-modal {
background: var(--bg-panel);
border-radius: 14px;
width: min(820px, 100%);
max-height: 90vh;
display: flex;
flex-direction: column;
border: 1px solid var(--border);
overflow: hidden;
box-shadow: 0 32px 80px rgba(0, 0, 0, 0.25);
}
.prompt-template-modal-head {
display: flex;
gap: 12px;
align-items: flex-start;
padding: 18px 18px 0;
}
.prompt-template-modal-titles { flex: 1; min-width: 0; }
.prompt-template-modal-titles h2 {
font-size: 17px;
margin: 0 0 6px 0;
color: var(--text);
}
.prompt-template-modal-titles p {
margin: 0;
font-size: 13px;
color: var(--text-muted);
line-height: 1.45;
}
.prompt-template-modal-tags {
display: flex;
flex-wrap: wrap;
gap: 6px;
padding: 10px 18px 0;
}
.prompt-template-modal-body {
display: flex;
flex-direction: column;
gap: 16px;
padding: 16px 18px;
overflow: auto;
}
.prompt-template-modal-asset {
position: relative;
display: flex;
align-items: center;
justify-content: center;
background: #000;
border-radius: 8px;
overflow: hidden;
max-height: 360px;
}
.prompt-template-modal-asset img,
.prompt-template-modal-asset video {
max-width: 100%;
max-height: 360px;
display: block;
}
.prompt-template-modal-asset-image-trigger {
display: block;
padding: 0;
margin: 0;
border: 0;
background: transparent;
cursor: zoom-in;
max-height: 360px;
line-height: 0;
}
.prompt-template-modal-asset-image-trigger img {
transition: transform 200ms ease;
}
.prompt-template-modal-asset-image-trigger:hover img,
.prompt-template-modal-asset-image-trigger:focus-visible img {
transform: scale(1.02);
}
.prompt-template-modal-asset-expand {
position: absolute;
top: 10px;
right: 10px;
z-index: 1;
display: inline-flex;
align-items: center;
gap: 6px;
padding: 6px 10px;
border: 0;
border-radius: 999px;
background: rgba(0, 0, 0, 0.55);
color: #fff;
font-size: 11px;
font-weight: 600;
letter-spacing: 0.01em;
cursor: pointer;
backdrop-filter: blur(8px);
-webkit-backdrop-filter: blur(8px);
opacity: 0.78;
transition: opacity 120ms ease, background 120ms ease;
}
.prompt-template-modal-asset:hover .prompt-template-modal-asset-expand,
.prompt-template-modal-asset-expand:hover,
.prompt-template-modal-asset-expand:focus-visible {
opacity: 1;
background: rgba(0, 0, 0, 0.72);
}
.prompt-template-lightbox-backdrop {
position: fixed;
inset: 0;
z-index: 1600;
background: rgba(8, 9, 12, 0.94);
display: flex;
align-items: center;
justify-content: center;
padding: 48px;
cursor: zoom-out;
animation: prompt-template-lightbox-fade 140ms ease-out;
}
@keyframes prompt-template-lightbox-fade {
from { opacity: 0; }
to { opacity: 1; }
}
.prompt-template-lightbox-media {
max-width: 100%;
max-height: 100%;
width: auto;
height: auto;
display: block;
border-radius: 10px;
box-shadow: 0 28px 80px rgba(0, 0, 0, 0.6);
cursor: default;
background: #000;
}
.prompt-template-lightbox-close {
position: fixed;
top: 18px;
right: 18px;
width: 40px;
height: 40px;
display: inline-flex;
align-items: center;
justify-content: center;
border: 0;
border-radius: 999px;
background: rgba(255, 255, 255, 0.14);
color: #fff;
cursor: pointer;
backdrop-filter: blur(10px);
-webkit-backdrop-filter: blur(10px);
transition: background 120ms ease, transform 120ms ease;
}
.prompt-template-lightbox-close:hover,
.prompt-template-lightbox-close:focus-visible {
background: rgba(255, 255, 255, 0.26);
transform: scale(1.05);
}
@media (max-width: 640px) {
.prompt-template-lightbox-backdrop { padding: 16px; }
.prompt-template-lightbox-close { top: 12px; right: 12px; }
}
.prompt-template-modal-prompt {
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-subtle);
display: flex;
flex-direction: column;
}
.prompt-template-modal-prompt-head {
display: flex;
align-items: center;
justify-content: space-between;
padding: 8px 12px;
border-bottom: 1px solid var(--border);
}
.prompt-template-modal-prompt-label {
font-size: 11px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
}
.prompt-template-modal-prompt-body {
margin: 0;
padding: 12px;
white-space: pre-wrap;
word-break: break-word;
font-family: var(--font-mono, ui-monospace, monospace);
font-size: 12px;
line-height: 1.5;
max-height: 320px;
overflow: auto;
}
.prompt-template-modal-foot {
display: flex;
justify-content: space-between;
align-items: center;
gap: 12px;
padding: 12px 18px;
border-top: 1px solid var(--border);
font-size: 11px;
color: var(--text-faint);
}
.prompt-template-license {
padding: 1px 6px;
background: var(--bg-subtle);
border-radius: 4px;
color: var(--text-muted);
}
/* Prompt template picker — reuses the design-system picker shell so the
trigger / popover already look right. We only restyle the avatar (image
thumb) and add the editable prompt body block below the trigger. */
.prompt-template-picker .prompt-template-avatar {
background: var(--bg-subtle);
}
.prompt-template-picker .prompt-template-avatar img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
.prompt-template-picker .prompt-template-avatar.fallback {
color: var(--text-muted);
}
.prompt-template-edit {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 10px;
padding: 10px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
}
.prompt-template-edit-head {
display: flex;
flex-direction: column;
gap: 2px;
}
.prompt-template-edit-label {
font-size: 11.5px;
font-weight: 600;
color: var(--text);
letter-spacing: 0.01em;
}
.prompt-template-edit-hint {
font-size: 10.5px;
color: var(--text-muted);
line-height: 1.4;
}
.prompt-template-edit-textarea {
width: 100%;
min-height: 96px;
padding: 8px 10px;
font-size: 12px;
line-height: 1.5;
font-family: inherit;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-sm);
color: var(--text);
resize: vertical;
}
.prompt-template-edit-textarea:focus {
outline: none;
border-color: var(--accent);
box-shadow: 0 0 0 1px var(--accent);
}
.prompt-template-edit-empty {
margin-top: 6px;
font-size: 11px;
color: var(--text-muted);
font-style: italic;
}
.prompt-template-error {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin-top: 8px;
padding: 8px 10px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-left: 3px solid var(--danger, #c0392b);
border-radius: var(--radius-sm);
font-size: 12px;
color: var(--text);
}
.prompt-template-error-msg {
flex: 1;
min-width: 0;
}
.prompt-template-error-retry {
flex: none;
font-size: 11.5px !important;
padding: 4px 10px !important;
}
/* ============================================================
Pet — Codex-style floating companion + settings cards
------------------------------------------------------------
The overlay anchors to the bottom-right via inline right/bottom
styles set by PetOverlay. The accent color cascades through the
`--pet-accent` custom property so every pet variant gets the
same halo / bubble border / focus ring without a class explosion.
============================================================ */
.pet-overlay {
position: fixed;
z-index: 90;
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 10px;
pointer-events: none;
--pet-accent: var(--accent);
}
.pet-overlay > * { pointer-events: auto; }
.pet-sprite {
position: relative;
/* The overlay sprite was 56px which read as a tiny postage stamp
against a 1280px+ canvas — bumped to 96px so the pet feels like
a present companion rather than a thumbnail. The image-mode
children inherit width/height: 100% via .pet-image, so atlas /
strip / static pets all scale up automatically. */
width: 96px;
height: 96px;
background: transparent;
border: 0;
box-shadow: none;
display: flex;
align-items: center;
justify-content: center;
cursor: grab;
user-select: none;
touch-action: none;
transition: transform 160ms ease;
}
.pet-sprite:hover {
transform: translateY(-2px);
}
.pet-sprite:active { cursor: grabbing; }
.pet-sprite-glyph {
/* Glyph font-size scales with the sprite box (~0.55 ratio) so
emoji-only built-ins and the avatar mark stay legible at the
larger overlay size. */
font-size: 52px;
line-height: 1;
animation: var(--pet-anim, pet-float) 3.4s ease-in-out infinite;
filter: drop-shadow(0 1px 0 rgba(0,0,0,0.08));
}
.pet-sprite-shadow {
position: absolute;
bottom: -12px;
left: 50%;
width: 64px;
height: 8px;
background: rgba(0, 0, 0, 0.18);
border-radius: 50%;
filter: blur(4px);
transform: translateX(-50%);
animation: pet-shadow 3.4s ease-in-out infinite;
}
@keyframes pet-bounce {
0%, 100% { transform: translateY(0); }
50% { transform: translateY(-6px); }
}
@keyframes pet-sway {
0%, 100% { transform: rotate(-4deg); }
50% { transform: rotate(4deg); }
}
@keyframes pet-float {
0%, 100% { transform: translateY(0) rotate(0); }
50% { transform: translateY(-4px) rotate(2deg); }
}
@keyframes pet-wiggle {
0%, 100% { transform: rotate(0); }
25% { transform: rotate(-6deg); }
75% { transform: rotate(6deg); }
}
@keyframes pet-shadow {
0%, 100% { transform: translateX(-50%) scale(1); opacity: 0.18; }
50% { transform: translateX(-50%) scale(0.85); opacity: 0.12; }
}
@media (prefers-reduced-motion: reduce) {
.pet-sprite-glyph,
.pet-sprite-shadow { animation: none !important; }
}
.pet-bubble {
max-width: 240px;
background: var(--bg-panel);
color: var(--text);
border: 1px solid var(--pet-accent);
border-radius: 12px;
padding: 10px 12px 8px;
box-shadow: var(--shadow-md);
font-size: 12.5px;
line-height: 1.4;
position: relative;
animation: pet-bubble-in 200ms ease-out;
}
.pet-bubble::after {
content: '';
position: absolute;
right: 18px;
bottom: -6px;
width: 12px;
height: 12px;
background: var(--bg-panel);
border-right: 1px solid var(--pet-accent);
border-bottom: 1px solid var(--pet-accent);
transform: rotate(45deg);
}
.pet-bubble-name {
font-weight: 600;
font-size: 12px;
color: var(--pet-accent);
margin-bottom: 2px;
}
.pet-bubble-line {
color: var(--text);
}
.pet-bubble-actions {
margin-top: 8px;
display: flex;
gap: 6px;
flex-wrap: wrap;
}
.pet-bubble-btn {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 11px;
padding: 3px 8px;
border-radius: var(--radius-pill);
background: var(--bg-subtle);
color: var(--text-muted);
border: 1px solid var(--border);
cursor: pointer;
}
.pet-bubble-btn:hover {
background: var(--bg-muted);
color: var(--text);
border-color: var(--border-strong);
}
@keyframes pet-bubble-in {
from { opacity: 0; transform: translateY(4px) scale(0.96); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
/* ----- Entry sidebar adopt pill ----- */
.pet-pill {
position: relative;
}
.pet-pill .pet-pill-glyph {
font-size: 14px;
line-height: 1;
}
.pet-pill-fresh {
border-color: var(--accent);
color: var(--text);
background: var(--accent-tint);
}
.pet-pill-fresh:hover {
background: var(--accent-soft);
border-color: var(--accent);
}
.pet-pill-dot {
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--accent);
box-shadow: 0 0 0 3px var(--accent-tint);
margin-left: 2px;
}
/* ----- Settings → Pets ----- */
.pet-wake-controls {
display: inline-flex;
align-items: center;
gap: 6px;
}
.seg-btn.small {
padding: 4px 10px !important;
font-size: 12px !important;
display: inline-flex;
align-items: center;
gap: 4px;
border-radius: var(--radius-pill);
border: 1px solid var(--border);
background: var(--bg-subtle);
color: var(--text-muted);
cursor: pointer;
}
.seg-btn.small.active {
background: var(--accent-tint);
color: var(--accent-strong);
border-color: var(--accent);
}
.seg-btn.small[disabled] {
opacity: 0.5;
cursor: not-allowed;
}
/* Pet source tabs — pill row that splits the panel into three
exclusive surfaces (built-in / custom / community). Sits flush
between the section head and the active tab's content so the user
reads it as "pick a source, then pick a pet inside it". */
.pet-tabs {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 12px;
}
.pet-tabs .subtab-pill {
align-self: flex-start;
}
.pet-tabs-hint {
margin: 0;
}
.pet-grid {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
gap: 10px;
margin-top: 4px;
}
/* The Community tab stacks the codex grid + hatch panel; flatten
their default top margins so the spacing reads as one column
rather than two ad-hoc cards. */
.pet-community {
display: flex;
flex-direction: column;
gap: 14px;
margin-top: 4px;
}
.pet-community .pet-codex,
.pet-community .pet-hatch {
margin-top: 0;
}
/* Custom tab dashed wrapper — strip the top margin so it tucks
directly under the tab pills. */
.pet-tabs + .pet-custom,
.pet-tabs + div + .pet-custom {
margin-top: 4px;
}
/* Highlight the codex card whose name + image match the user's
current adoption (community pets land in the custom slot, so we
piggy-back on the same "active" affordance used by built-ins). */
.pet-codex-card.active {
border-color: var(--accent);
box-shadow: 0 0 0 1px var(--accent) inset;
}
.pet-card {
--pet-accent: var(--accent);
position: relative;
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border-radius: var(--radius);
background: var(--bg-panel);
border: 1px solid var(--border);
cursor: pointer;
text-align: left;
color: var(--text);
transition: border-color 120ms ease, transform 120ms ease;
}
.pet-card:hover {
border-color: var(--border-strong);
transform: translateY(-1px);
}
.pet-card.active {
border-color: var(--pet-accent);
box-shadow: 0 0 0 1px var(--pet-accent) inset;
background: var(--bg-panel);
}
.pet-card-glyph {
font-size: 28px;
line-height: 1;
width: 40px;
height: 40px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
background: color-mix(in srgb, var(--pet-accent) 14%, transparent);
}
.pet-card-meta {
display: flex;
flex-direction: column;
min-width: 0;
flex: 1;
}
.pet-card-name {
font-weight: 600;
font-size: 13px;
color: var(--text-strong);
}
.pet-card-flavor {
font-size: 11.5px;
color: var(--text-muted);
line-height: 1.3;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.pet-card-cta,
.pet-card-badge {
position: absolute;
top: 8px;
right: 8px;
font-size: 10.5px;
padding: 2px 7px;
border-radius: var(--radius-pill);
background: var(--bg-subtle);
color: var(--text-muted);
border: 1px solid var(--border);
display: inline-flex;
align-items: center;
gap: 3px;
}
.pet-card-badge {
background: color-mix(in srgb, var(--pet-accent) 16%, transparent);
border-color: var(--pet-accent);
color: var(--pet-accent);
}
.pet-custom {
margin-top: 18px;
padding: 14px;
border-radius: var(--radius);
border: 1px dashed var(--border-strong);
background: var(--bg-subtle);
display: flex;
flex-direction: column;
gap: 12px;
}
.pet-custom-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.pet-custom-head h4 {
margin: 0 0 4px;
font-size: 13px;
}
.pet-custom-preview {
display: flex;
align-items: center;
gap: 12px;
padding: 10px 12px;
border-radius: var(--radius);
background: var(--bg-panel);
border: 1px solid var(--border);
}
.pet-custom-sprite {
font-size: 32px;
line-height: 1;
width: 48px;
height: 48px;
/* Lock the sprite to a perfect square inside the flex preview row.
Without `flex-shrink: 0`, a long pet name or greeting in the
adjacent bubble shrinks the 48px box horizontally, squashing
the sprite and breaking the round halo. */
flex: 0 0 48px;
border-radius: 50%;
display: inline-flex;
align-items: center;
justify-content: center;
background: color-mix(in srgb, var(--pet-accent, var(--accent)) 14%, transparent);
}
.pet-custom-bubble {
display: flex;
flex-direction: column;
gap: 2px;
font-size: 12.5px;
color: var(--text);
/* Allow the text column to shrink past its intrinsic content width
so long greetings wrap instead of pushing the sprite. */
min-width: 0;
}
.pet-custom-bubble strong {
color: var(--pet-accent, var(--accent));
}
.pet-custom-fields {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
}
.pet-swatches {
display: flex;
flex-wrap: wrap;
gap: 6px;
align-items: center;
}
.pet-swatch {
width: 22px;
height: 22px;
border-radius: 50%;
border: 2px solid transparent;
cursor: pointer;
padding: 0;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
}
.pet-swatch.active {
border-color: var(--text-strong);
}
.pet-swatch-picker {
width: 22px;
height: 22px;
border: 1px dashed var(--border-strong);
border-radius: 50%;
background: transparent;
padding: 0;
cursor: pointer;
}
/* ============================================================
Pet — discovery surfaces (right rail, welcome teaser, composer)
============================================================ */
/* Right-side rail in the entry view. Renders as a third grid column
(the entry's gridTemplateColumns is set inline to `… 1fr auto`). */
.pet-rail {
width: 232px;
border-left: 1px solid var(--border);
background: var(--bg-panel);
padding: 18px 14px;
display: flex;
flex-direction: column;
gap: 12px;
overflow-y: auto;
}
.pet-rail.collapsed {
width: 36px;
padding: 18px 4px;
align-items: center;
}
.pet-rail-toggle {
display: inline-flex;
flex-direction: column;
align-items: center;
gap: 6px;
padding: 6px 4px;
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: var(--radius);
color: var(--text-muted);
cursor: pointer;
width: 100%;
}
.pet-rail-toggle:hover {
background: var(--bg-muted);
color: var(--text);
}
.pet-rail-toggle-glyph {
font-size: 18px;
line-height: 1;
}
.pet-rail-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 6px;
}
.pet-rail-head-actions {
display: inline-flex;
align-items: center;
gap: 4px;
flex-shrink: 0;
}
.pet-rail-title {
display: inline-flex;
align-items: center;
gap: 6px;
color: var(--text);
}
.pet-rail-title strong {
font-size: 12px;
letter-spacing: 0.06em;
text-transform: uppercase;
}
.pet-rail-collapse {
width: 22px;
height: 22px;
padding: 0;
border-radius: var(--radius-sm);
border: 1px solid var(--border);
background: var(--bg-subtle);
color: var(--text);
cursor: pointer;
display: inline-flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
transition: background 120ms ease, border-color 120ms ease, color 120ms ease;
}
.pet-rail-collapse > svg {
flex-shrink: 0;
}
.pet-rail-collapse:hover {
background: var(--bg-muted);
border-color: var(--border-strong);
color: var(--text-strong);
}
.pet-rail-collapse:focus-visible {
outline: none;
box-shadow: 0 0 0 2px rgba(201, 100, 66, 0.32);
border-color: var(--accent);
}
.pet-rail-hint {
font-size: 11.5px;
color: var(--text-muted);
margin: 0;
line-height: 1.45;
}
.pet-rail-status {
display: flex;
align-items: center;
gap: 6px;
}
.pet-rail-status-pill {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 8px;
border-radius: var(--radius-pill);
font-size: 11px;
background: var(--accent-tint);
color: var(--accent-strong);
border: 1px solid var(--accent);
cursor: pointer;
}
.pet-rail-fresh {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 8px;
border-radius: var(--radius-pill);
font-size: 11px;
background: var(--accent-tint);
color: var(--accent-strong);
border: 1px dashed var(--accent);
}
.pet-rail-list {
display: flex;
flex-direction: column;
gap: 6px;
}
.pet-rail-item {
--pet-accent: var(--accent);
display: grid;
grid-template-columns: 32px 1fr auto;
align-items: center;
gap: 8px;
padding: 6px 8px;
border-radius: var(--radius);
background: var(--bg-panel);
border: 1px solid transparent;
cursor: pointer;
text-align: left;
color: var(--text);
}
.pet-rail-item:hover {
background: var(--bg-subtle);
border-color: var(--border);
}
.pet-rail-item.active {
border-color: var(--pet-accent);
background: color-mix(in srgb, var(--pet-accent) 8%, transparent);
}
.pet-rail-item.custom {
border-style: dashed;
border-color: var(--border-strong);
}
.pet-rail-item.custom.active {
border-style: solid;
border-color: var(--pet-accent);
}
.pet-rail-item-glyph {
width: 32px;
height: 32px;
border-radius: 50%;
font-size: 18px;
line-height: 1;
display: inline-flex;
align-items: center;
justify-content: center;
background: color-mix(in srgb, var(--pet-accent) 14%, transparent);
}
.pet-rail-item-meta {
display: flex;
flex-direction: column;
min-width: 0;
}
.pet-rail-item-name {
font-size: 12.5px;
font-weight: 600;
color: var(--text-strong);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pet-rail-item-flavor {
font-size: 10.5px;
color: var(--text-muted);
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.pet-rail-customize {
margin-top: 6px;
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
padding: 6px 10px;
border-radius: var(--radius);
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
cursor: pointer;
font-size: 12px;
}
.pet-rail-customize:hover {
background: var(--bg-muted);
color: var(--text);
border-color: var(--border-strong);
}
/* Hide the rail on small viewports so it does not crowd the main column. */
@media (max-width: 1100px) {
.pet-rail:not(.collapsed) {
display: none;
}
}
/* ----- Welcome dialog teaser ----- */
.welcome-pet-teaser {
margin-top: 10px;
display: flex;
align-items: center;
gap: 10px;
padding: 8px 12px;
background: linear-gradient(135deg, var(--accent-tint) 0%, var(--accent-soft) 100%);
border: 1px solid var(--accent);
border-radius: var(--radius);
cursor: pointer;
text-align: left;
color: var(--text);
width: 100%;
}
.welcome-pet-teaser:hover {
filter: brightness(1.02);
}
.welcome-pet-glyph {
font-size: 24px;
line-height: 1;
width: 36px;
height: 36px;
border-radius: 50%;
background: var(--bg-panel);
border: 1px solid var(--accent);
display: inline-flex;
align-items: center;
justify-content: center;
flex: none;
}
.welcome-pet-copy {
display: flex;
flex-direction: column;
flex: 1;
min-width: 0;
}
.welcome-pet-copy strong {
font-size: 12.5px;
color: var(--text-strong);
}
.welcome-pet-copy span {
font-size: 11px;
color: var(--text-muted);
line-height: 1.35;
}
.welcome-pet-cta {
display: inline-flex;
align-items: center;
gap: 4px;
font-size: 11.5px;
color: var(--accent-strong);
font-weight: 600;
white-space: nowrap;
}
/* ----- Composer pet button + popover ----- */
.composer-pet-wrap {
position: relative;
display: inline-flex;
}
.composer-pet {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 10px;
border-radius: var(--radius-pill);
background: var(--bg-subtle);
border: 1px solid var(--border);
color: var(--text-muted);
cursor: pointer;
font-size: 12px;
}
.composer-pet:hover {
background: var(--bg-muted);
color: var(--text);
border-color: var(--border-strong);
}
.composer-pet.adopted {
border-color: var(--accent);
color: var(--accent-strong);
background: var(--accent-tint);
}
.composer-pet-glyph {
font-size: 14px;
line-height: 1;
}
.composer-pet-label {
font-weight: 500;
}
.composer-pet-menu {
position: absolute;
bottom: calc(100% + 6px);
right: 0;
z-index: 30;
width: 260px;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
padding: 10px;
display: flex;
flex-direction: column;
gap: 8px;
}
.composer-pet-menu-head {
display: flex;
flex-direction: column;
gap: 2px;
padding: 0 2px 6px;
border-bottom: 1px solid var(--border-soft);
}
.composer-pet-menu-head strong {
font-size: 12px;
color: var(--text-strong);
}
.composer-pet-menu-head span {
font-size: 10.5px;
color: var(--text-muted);
font-family: var(--mono);
}
.composer-pet-menu-row {
display: inline-flex;
align-items: center;
gap: 6px;
padding: 4px 8px;
border-radius: var(--radius-sm);
background: transparent;
border: 1px solid transparent;
color: var(--text-muted);
cursor: pointer;
font-size: 12px;
text-align: left;
}
.composer-pet-menu-row:hover {
background: var(--bg-subtle);
color: var(--text);
}
.composer-pet-menu-row.toggle {
background: var(--bg-subtle);
border-color: var(--border);
}
.composer-pet-menu-grid {
display: grid;
grid-template-columns: repeat(4, 1fr);
gap: 4px;
}
.composer-pet-menu-pet {
--pet-accent: var(--accent);
display: flex;
flex-direction: column;
align-items: center;
gap: 2px;
padding: 6px 2px;
border-radius: var(--radius-sm);
background: var(--bg-subtle);
border: 1px solid transparent;
cursor: pointer;
font-size: 10.5px;
color: var(--text-muted);
}
.composer-pet-menu-pet:hover {
border-color: var(--border-strong);
color: var(--text);
}
.composer-pet-menu-pet.active {
border-color: var(--pet-accent);
background: color-mix(in srgb, var(--pet-accent) 12%, transparent);
color: var(--text);
}
.composer-pet-menu-pet span:first-child {
font-size: 18px;
line-height: 1;
}
.composer-pet-menu-row.settings {
border-top: 1px solid var(--border-soft);
margin-top: 2px;
padding-top: 8px;
border-radius: 0;
border-bottom: 1px solid transparent;
border-left: 1px solid transparent;
border-right: 1px solid transparent;
}
/* ============================================================
Pet — uploaded image / spritesheet rendering
------------------------------------------------------------
The face element switches between an emoji glyph and an
image/spritesheet via the PetSpriteFace component. Static
images inherit the float animation from .pet-sprite-glyph;
spritesheets get their own pet-frames keyframes which the
component drives with an inline `animation: …` string so
each pet can choose its own (frames, fps) combo.
============================================================ */
.pet-image {
display: inline-block;
background-position: 0 0;
background-repeat: no-repeat;
background-size: 100% 100%;
width: 100%;
height: 100%;
/* Pixel art-friendly upscale so 32×32 sheets stay crisp at 56 px. */
image-rendering: pixelated;
image-rendering: -moz-crisp-edges;
}
.pet-image.static {
/* Single static image — let the parent .pet-sprite-glyph float
animation drive subtle movement. */
background-size: contain;
background-position: center;
}
/* Spritesheet keyframe used by PetSpriteFace inline animation. The
from/to span 0% → 100%, which CSS resolves against
(container_width background_width). With background-size set to
`${frames * 100}% 100%` each `steps()` tick lands on a frame edge. */
@keyframes pet-frames {
from { background-position-x: 0%; }
to { background-position-x: 100%; }
}
/* Full-atlas mode: the sprite renders the active row from a Codex
8x9 grid. background-position-y is set inline to the row offset and
the keyframe walks frames inside that row. We use a CSS variable
for the endpoint so a single keyframe block can drive any row's
`frames`/`cols` combination — `--pet-atlas-end-x` is set per row by
PetSpriteFace based on `frames / (cols - 1) * 100%`. */
.pet-image.atlas {
background-repeat: no-repeat;
/* The sprite element switches rows on the fly; smooth out the
row transitions so direction changes feel less jarring without
blurring the per-frame `steps()` cadence. */
transition: background-position-y 220ms ease;
}
@keyframes pet-atlas-frames {
from { background-position-x: 0%; }
to { background-position-x: var(--pet-atlas-end-x, 100%); }
}
@media (prefers-reduced-motion: reduce) {
.pet-image.frames,
.pet-image.atlas { animation: none !important; background-position-x: 0% !important; }
}
/* PetSettings — upload row, frames/fps grid, error caption */
.pet-image-controls {
display: flex;
flex-direction: column;
gap: 6px;
margin-top: 4px;
padding: 10px;
border-radius: var(--radius);
background: var(--bg-panel);
border: 1px solid var(--border);
}
.pet-image-row {
display: inline-flex;
align-items: center;
gap: 6px;
flex-wrap: wrap;
}
.seg-btn.small.ghost {
background: transparent;
border-color: var(--border);
color: var(--text-muted);
}
.seg-btn.small.ghost:hover {
background: var(--bg-subtle);
color: var(--text);
border-color: var(--border-strong);
}
.pet-image-error {
color: var(--red) !important;
}
.pet-image-frames {
margin-top: 6px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 8px;
}
.pet-image-frames .field input {
width: 100%;
}
/* Make the custom-pet preview / settings sprite respect the rounded
accent halo used for emoji glyphs even when an image is rendered. */
.pet-custom-sprite {
overflow: hidden;
}
/* --- Codex hatch-pet atlas import + AI generation panels ------------ */
.pet-atlas-preview {
margin-top: 14px;
padding: 14px;
border: 1px solid var(--border);
border-radius: 12px;
background: var(--surface);
display: grid;
gap: 12px;
}
.pet-atlas-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.pet-atlas-head strong {
font-size: 13px;
font-weight: 600;
color: var(--text);
}
.pet-atlas-thumb {
width: 100%;
aspect-ratio: 1536 / 1872;
max-height: 240px;
background-repeat: no-repeat;
background-position: center;
background-size: contain;
background-color: var(--surface-2, #f6f4ee);
border-radius: 8px;
border: 1px solid var(--border);
image-rendering: pixelated;
}
.pet-atlas-rows {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
gap: 6px;
}
.pet-atlas-row {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 2px;
padding: 8px 10px;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg);
cursor: pointer;
font: inherit;
text-align: left;
transition: border-color 120ms ease, background 120ms ease;
}
.pet-atlas-row:hover {
border-color: var(--accent);
}
.pet-atlas-row.active {
border-color: var(--accent);
background: color-mix(in srgb, var(--accent) 10%, transparent);
}
.pet-atlas-row[disabled] {
opacity: 0.55;
cursor: progress;
}
.pet-atlas-row-name {
font-size: 12px;
font-weight: 600;
color: var(--text);
}
.pet-atlas-row-meta {
font-size: 11px;
color: var(--text-muted);
}
.pet-atlas-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
}
/* "Hatch with AI" panel */
.pet-hatch {
margin-top: 14px;
padding: 14px;
border: 1px dashed var(--border);
border-radius: 12px;
background: color-mix(in srgb, var(--accent) 4%, transparent);
display: grid;
gap: 10px;
}
.pet-hatch-head h4 {
margin: 0 0 4px 0;
font-size: 13px;
font-weight: 600;
}
.pet-hatch-prompt {
margin: 0;
padding: 10px 12px;
background: var(--bg);
border: 1px solid var(--border);
border-radius: 8px;
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
font-size: 11px;
line-height: 1.5;
color: var(--text);
max-height: 200px;
overflow: auto;
white-space: pre-wrap;
word-break: break-word;
}
.pet-hatch-actions {
display: flex;
gap: 8px;
}
.pet-hatch-foot {
margin: 0;
}
/* "Recently hatched" — Codex pets discovered under ~/.codex/pets/ */
.pet-codex {
margin-top: 14px;
padding: 14px;
border: 1px solid var(--border);
border-radius: 12px;
background: var(--surface);
display: grid;
gap: 10px;
}
.pet-codex-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 12px;
}
.pet-codex-head h4 {
margin: 0 0 4px 0;
font-size: 13px;
font-weight: 600;
}
/* Right-aligned button cluster in the codex head — keeps the
"Download community pets" + "Refresh" buttons on a single row even
when the section title wraps. */
.pet-codex-head-actions {
display: flex;
gap: 6px;
flex-wrap: wrap;
justify-content: flex-end;
}
.pet-codex-empty {
margin: 4px 0 0 0;
}
/* Inline status line shown after a community sync completes. Stays in
the section flow so the result reads as part of the same control
group as the trigger button. The error variant tints toward the
accent without screaming red — sync errors are usually transient
network blips. */
.pet-codex-sync-status {
margin: 6px 0 8px 0;
padding: 6px 10px;
border-radius: 6px;
background: var(--bg-subtle);
border: 1px solid var(--border);
font-size: 12px;
color: var(--text-muted);
}
.pet-codex-sync-status.error {
background: color-mix(in srgb, var(--accent) 8%, var(--bg-subtle));
border-color: color-mix(in srgb, var(--accent) 30%, var(--border));
color: var(--text-strong);
}
.pet-codex-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
gap: 10px;
}
.pet-codex-card {
display: grid;
grid-template-columns: 56px 1fr auto;
align-items: center;
gap: 10px;
padding: 10px;
border: 1px solid var(--border);
border-radius: 10px;
background: var(--bg);
}
.pet-codex-thumb {
position: relative;
width: 56px;
height: 56px;
border-radius: 8px;
border: 1px solid var(--border);
background-color: var(--surface-2, #f6f4ee);
background-image: var(--pet-codex-src);
background-repeat: no-repeat;
/* Show only the top-left cell of the 8x9 atlas — that is the
`idle` row, frame 0, and reads as a recognizable still even
before adoption. */
background-position: 0 0;
background-size: 800% 900%;
image-rendering: pixelated;
}
/* Hover preview — a larger floating overlay that plays through every
cell of the 8x9 Codex atlas so users can see what animations (idle,
running, waving, jumping, failed, waiting, …) the pet has before they
adopt it. The overlay is purely decorative: pointer-events: none
prevents it from stealing hover from the card, and aria-hidden keeps
it out of the accessibility tree. */
.pet-codex-thumb-preview {
position: absolute;
bottom: calc(100% + 8px);
left: 50%;
width: 128px;
/* 128 * (208/192) ≈ 138.7 — matches a single atlas cell aspect. */
height: 139px;
border-radius: 10px;
border: 1px solid var(--border);
background-color: var(--surface-2, #f6f4ee);
background-image: var(--pet-codex-src);
background-repeat: no-repeat;
background-position: 0% 0%;
background-size: 800% 900%;
image-rendering: pixelated;
box-shadow: 0 14px 28px rgba(0, 0, 0, 0.22);
opacity: 0;
pointer-events: none;
transform: translate(-50%, 6px) scale(0.82);
transform-origin: 50% 100%;
transition:
opacity 140ms ease,
transform 160ms ease;
z-index: 20;
}
.pet-codex-card:hover .pet-codex-thumb-preview,
.pet-codex-card:focus-within .pet-codex-thumb-preview {
opacity: 1;
transform: translate(-50%, 0) scale(1);
/* 8 column steps (1 row) in 0.6s → ~13 fps per animation, then the row
index advances every 0.6s for a full 5.4s sweep through all 9 rows.
Animating background-position-x + -y as two independent animations
keeps the nested loop in pure CSS. */
animation:
pet-codex-preview-col 0.6s steps(8, jump-none) infinite,
pet-codex-preview-row 5.4s steps(9, jump-none) infinite;
}
@keyframes pet-codex-preview-col {
from { background-position-x: 0%; }
to { background-position-x: 100%; }
}
@keyframes pet-codex-preview-row {
from { background-position-y: 0%; }
to { background-position-y: 100%; }
}
@media (prefers-reduced-motion: reduce) {
.pet-codex-card:hover .pet-codex-thumb-preview,
.pet-codex-card:focus-within .pet-codex-thumb-preview {
animation: none;
background-position: 0% 0%;
}
}
.pet-codex-meta {
display: grid;
gap: 2px;
min-width: 0;
}
.pet-codex-meta strong {
font-size: 12px;
font-weight: 600;
color: var(--text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.pet-codex-meta span {
font-size: 11px;
color: var(--text-muted);
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
/* Slash-command popover in the chat composer */
.slash-popover {
position: absolute;
bottom: 100%;
left: 0;
right: 0;
margin-bottom: 4px;
max-height: 260px;
overflow-y: auto;
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius);
box-shadow: var(--shadow-md);
z-index: 10;
padding: 6px;
}
.slash-popover-head {
display: flex;
align-items: baseline;
justify-content: space-between;
gap: 10px;
padding: 4px 6px 6px 6px;
border-bottom: 1px solid var(--border);
margin-bottom: 4px;
font-size: 11px;
color: var(--text-muted);
text-transform: uppercase;
letter-spacing: 0.04em;
}
.slash-popover-hint {
font-size: 10px;
text-transform: none;
letter-spacing: 0;
color: var(--text-muted);
}
.slash-item {
display: flex;
align-items: flex-start;
gap: 8px;
width: 100%;
background: transparent;
border: 1px solid transparent;
border-radius: 6px;
padding: 7px 8px;
text-align: left;
cursor: pointer;
font: inherit;
}
.slash-item:hover,
.slash-item.active {
background: var(--bg-subtle);
border-color: var(--border);
}
.slash-item-icon {
display: inline-flex;
align-items: center;
justify-content: center;
width: 22px;
height: 22px;
border-radius: 6px;
background: color-mix(in srgb, var(--accent) 12%, transparent);
color: var(--accent);
flex-shrink: 0;
margin-top: 1px;
}
.slash-item-body {
display: grid;
gap: 2px;
min-width: 0;
flex: 1;
}
.slash-item-row {
display: flex;
align-items: baseline;
gap: 8px;
}
.slash-item-label {
font-size: 12px;
font-weight: 600;
color: var(--text);
background: transparent;
padding: 0;
}
.slash-item-arg {
font-size: 10px;
color: var(--text-muted);
font-family: var(--font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);
}
.slash-item-desc {
font-size: 11px;
color: var(--text-muted);
line-height: 1.35;
}
/* --- Arabic & Persian Comfort Pass --- */
[dir="rtl"] {
--sans: "Cairo", "Inter", "Vazirmatn", "Noto Sans Arabic", "Segoe UI Arabic", "Tahoma", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
}
/* Scope line-height increase to prose and chat to avoid breaking compact UI chrome */
[dir="rtl"] .prose,
[dir="rtl"] .chat-message,
[dir="rtl"] .msg .user-text {
line-height: 1.7;
}
[dir="rtl"] .avatar-item,
[dir="rtl"] .settings-tab,
[dir="rtl"] .ds-item-name {
text-align: right;
}
[dir="rtl"] .app-chrome-back svg,
[dir="rtl"] .back-btn svg,
[dir="rtl"] .icon-btn svg[data-lucide="chevron-left"],
[dir="rtl"] .icon-btn svg[data-lucide="chevron-right"],
[dir="rtl"] .icon-btn svg[data-lucide="arrow-left"],
[dir="rtl"] .icon-btn svg[data-lucide="arrow-right"],
[dir="rtl"] .newproj-tabs-arrow svg,
[dir="rtl"] .icon-only svg[data-lucide="chevron-left"],
[dir="rtl"] .icon-only svg[data-lucide="chevron-right"],
[dir="rtl"] .icon-only svg[data-lucide="arrow-left"],
[dir="rtl"] .icon-only svg[data-lucide="arrow-right"],
[dir="rtl"] .pet-rail-collapse svg,
[dir="rtl"] .welcome-pet-teaser svg {
transform: scaleX(-1);
}
[dir="rtl"] .title,
[dir="rtl"] .meta {
text-align: right;
}
/* ============================================================
Quick Switcher (Cmd/Ctrl+P file palette)
============================================================ */
.qs-overlay {
position: fixed;
inset: 0;
background: rgba(13, 12, 10, 0.32);
/* Sits in the modal tier (alongside prompt-template-modal-overlay) so
* the palette renders above any open context menus or popovers. */
z-index: 1500;
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 12vh;
}
.qs-palette {
width: min(560px, 92vw);
background: var(--bg-panel);
border: 1px solid var(--border);
border-radius: var(--radius-lg);
box-shadow: var(--shadow-lg);
display: flex;
flex-direction: column;
overflow: hidden;
color: var(--text);
}
.qs-input {
appearance: none;
border: 0;
outline: none;
background: transparent;
padding: 14px 16px;
font-size: 16px;
font-weight: 500;
color: var(--text);
border-bottom: 1px solid var(--border-soft);
}
.qs-input::placeholder {
color: var(--text-faint);
}
.qs-list {
max-height: 50vh;
overflow-y: auto;
padding: 4px 0;
}
.qs-empty {
padding: 20px 16px;
color: var(--text-muted);
text-align: center;
font-size: 13px;
}
.qs-row {
display: grid;
grid-template-columns: auto 1fr auto;
gap: 10px;
align-items: baseline;
padding: 7px 16px;
cursor: pointer;
border-left: 3px solid transparent;
}
.qs-row-active {
background: var(--accent-soft);
border-left-color: var(--accent);
}
.qs-name {
font-weight: 600;
font-size: 14px;
color: var(--text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.qs-path {
color: var(--text-muted);
font-size: 12.5px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
min-width: 0;
}
.qs-kind {
font-size: 10.5px;
letter-spacing: 0.06em;
text-transform: uppercase;
color: var(--text-faint);
font-weight: 600;
}
.qs-row-active .qs-kind {
color: var(--accent-strong);
}
.qs-footer {
display: flex;
gap: 14px;
padding: 8px 16px;
border-top: 1px solid var(--border-soft);
font-size: 11.5px;
color: var(--text-muted);
}
.qs-footer kbd {
background: var(--bg-subtle);
border: 1px solid var(--border);
border-radius: 3px;
padding: 0 4px;
margin-right: 2px;
font-family: ui-monospace, monospace;
font-size: 10px;
color: var(--text-muted);
}
/* Library section (Skills & Design Systems management) */
.library-toolbar {
display: flex;
flex-direction: column;
gap: 10px;
margin-bottom: 16px;
}
.library-search {
width: 100%;
padding: 8px 12px;
border: 1px solid var(--border);
border-radius: 8px;
font-size: 13px;
background: var(--bg);
color: var(--text);
outline: none;
}
.library-search:focus {
border-color: var(--accent);
}
.library-filters {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.library-content {
display: flex;
flex-direction: column;
gap: 20px;
}
.library-group {
display: flex;
flex-direction: column;
gap: 8px;
}
.library-group-title {
font-size: 13px;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
color: var(--text-muted);
display: flex;
align-items: center;
gap: 6px;
}
.library-group-count {
font-weight: 400;
font-size: 11px;
opacity: 0.6;
}
.library-card {
display: flex;
align-items: flex-start;
gap: 12px;
padding: 10px 12px;
border: 1px solid var(--border);
border-radius: 8px;
flex-wrap: wrap;
}
.library-card.disabled {
opacity: 0.45;
}
.library-card-info {
flex: 1;
min-width: 0;
}
.library-card-title-row {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 4px;
}
.library-card-name {
font-size: 14px;
font-weight: 600;
}
.library-card-badge {
font-size: 10px;
text-transform: uppercase;
letter-spacing: 0.05em;
padding: 1px 6px;
border-radius: 4px;
background: var(--accent-tint);
color: var(--accent);
font-weight: 500;
}
.library-card-desc {
font-size: 12px;
color: var(--text-muted);
line-height: 1.4;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.library-card-expand {
background: none;
border: none;
cursor: pointer;
padding: 4px;
color: var(--text-muted);
border-radius: 4px;
}
.library-card-expand:hover {
background: var(--border);
}
.library-ds-card {
position: relative;
display: flex;
flex-direction: column;
border: 1px solid var(--border);
border-radius: 12px;
overflow: hidden;
padding: 12px;
gap: 8px;
}
.library-ds-card.disabled {
opacity: 0.45;
}
.library-ds-card-content {
cursor: pointer;
}
.library-ds-swatches {
display: flex;
gap: 4px;
margin-bottom: 6px;
}
.library-ds-swatch {
width: 18px;
height: 18px;
border-radius: 4px;
border: 1px solid rgba(128, 128, 128, 0.2);
}
.library-ds-title {
font-size: 13px;
font-weight: 600;
margin-bottom: 2px;
}
.library-ds-summary {
font-size: 11px;
color: var(--text-muted);
line-height: 1.3;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.library-ds-card .toggle-switch {
align-self: flex-end;
}
.library-preview {
width: 100%;
padding: 12px;
border-top: 1px solid var(--border);
margin-top: 4px;
}
.library-preview-body {
font-size: 12px;
line-height: 1.5;
white-space: pre-wrap;
word-break: break-word;
max-height: 300px;
overflow-y: auto;
margin: 0;
color: var(--text-muted);
}
.library-empty {
text-align: center;
color: var(--text-muted);
font-size: 13px;
padding: 32px 0;
}
/* Toggle switch */
.toggle-switch {
position: relative;
display: inline-block;
width: 36px;
height: 20px;
flex-shrink: 0;
}
.toggle-switch input {
opacity: 0;
width: 0;
height: 0;
}
.toggle-slider {
position: absolute;
cursor: pointer;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: var(--border);
border-radius: 20px;
transition: background-color 0.2s;
}
.toggle-slider::before {
content: '';
position: absolute;
height: 14px;
width: 14px;
left: 3px;
bottom: 3px;
background-color: white;
border-radius: 50%;
transition: transform 0.2s;
}
.toggle-switch input:checked + .toggle-slider {
background-color: var(--accent);
}
.toggle-switch input:checked + .toggle-slider::before {
transform: translateX(16px);
}
.toggle-switch-sm {
width: 30px;
height: 17px;
}
.toggle-switch-sm .toggle-slider::before {
height: 11px;
width: 11px;
}
.toggle-switch-sm input:checked + .toggle-slider::before {
transform: translateX(13px);
}
/* Manual edit mode */
.manual-edit-workspace {
display: grid;
grid-template-columns: 240px minmax(420px, 1fr) 344px;
gap: 10px;
height: 100%;
min-height: 0;
padding: 10px;
background: var(--bg);
}
.manual-edit-canvas {
position: relative;
min-width: 0;
min-height: 0;
overflow: hidden;
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-panel);
}
.manual-edit-canvas iframe {
width: 100%;
height: 100%;
border: 0;
}
.manual-edit-layers,
.manual-edit-right {
min-height: 0;
}
.manual-edit-layers,
.manual-edit-modal,
.manual-edit-changes {
border: 1px solid var(--border);
border-radius: 8px;
background: var(--bg-panel);
}
.manual-edit-layers {
display: flex;
flex-direction: column;
overflow: hidden;
}
.manual-edit-panel-head {
display: flex;
align-items: center;
justify-content: space-between;
gap: 8px;
padding: 12px;
border-bottom: 1px solid var(--border);
}
.manual-edit-panel-head h3 {
margin: 0;
font-size: 13px;
}
.manual-edit-panel-head span {
color: var(--text-muted);
font-size: 11px;
}
.manual-edit-layer-list,
.manual-edit-history-list {
display: grid;
gap: 7px;
overflow: auto;
padding: 10px;
}
.manual-edit-layer-row {
display: grid;
gap: 3px;
width: 100%;
height: auto;
padding: 9px 10px;
text-align: left;
border: 1px solid var(--border);
border-radius: 7px;
background: var(--bg-panel);
}
.manual-edit-layer-row.selected {
border-color: var(--accent);
background: color-mix(in srgb, var(--accent) 8%, var(--bg-panel));
box-shadow: inset 3px 0 0 var(--accent);
}
.manual-edit-layer-row strong {
overflow: hidden;
font-size: 13px;
text-overflow: ellipsis;
}
.manual-edit-layer-row span {
color: var(--text-muted);
font-size: 11px;
}
.manual-edit-right {
display: flex;
flex-direction: column;
gap: 10px;
}
.manual-edit-modal {
display: flex;
flex-direction: column;
min-height: 0;
overflow: hidden;
box-shadow: 0 16px 40px rgba(15, 23, 42, 0.12);
}
.manual-edit-modal-head {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 10px;
padding: 13px;
border-bottom: 1px solid var(--border);
}
.manual-edit-modal-head span {
display: block;
color: var(--text-muted);
font-size: 10px;
font-weight: 700;
letter-spacing: .03em;
text-transform: uppercase;
}
.manual-edit-modal-head h3 {
max-width: 220px;
margin: 2px 0 0;
overflow: hidden;
font-size: 15px;
text-overflow: ellipsis;
white-space: nowrap;
}
.manual-edit-modal-head em {
flex: 0 0 auto;
padding: 4px 8px;
border: 1px solid var(--border);
border-radius: 999px;
color: var(--text-muted);
font-size: 11px;
font-style: normal;
}
.manual-edit-empty {
margin: 12px;
color: var(--text-muted);
font-size: 12px;
}
.manual-edit-meta {
display: flex;
align-items: center;
justify-content: space-between;
gap: 10px;
margin: 12px 12px 10px;
padding: 10px;
border: 1px solid var(--border);
border-radius: 7px;
background: var(--bg);
}
.manual-edit-meta strong,
.manual-edit-meta span,
.manual-edit-meta code {
display: block;
}
.manual-edit-meta span {
margin-top: 2px;
color: var(--text-muted);
font-size: 11px;
}
.manual-edit-meta code {
max-width: 120px;
overflow: hidden;
color: var(--text-muted);
font-size: 11px;
text-overflow: ellipsis;
white-space: nowrap;
}
.manual-edit-tabs {
display: grid;
grid-template-columns: repeat(5, minmax(0, 1fr));
gap: 5px;
padding: 0 12px 12px;
}
.manual-edit-tabs button {
min-height: 30px;
padding: 0 6px;
font-size: 11px;
text-transform: capitalize;
}
.manual-edit-tabs button.active {
color: var(--bg-panel);
border-color: var(--accent);
background: var(--accent);
}
.manual-edit-tab-body {
display: grid;
gap: 10px;
min-height: 0;
padding: 0 12px 12px;
overflow: auto;
}
.manual-edit-field {
display: grid;
gap: 6px;
}
.manual-edit-field span {
color: var(--text);
font-size: 12px;
font-weight: 650;
}
.manual-edit-field input,
.manual-edit-field textarea,
.manual-edit-field select {
width: 100%;
border: 1px solid var(--border);
border-radius: 6px;
padding: 8px 9px;
color: var(--text);
background: var(--bg-panel);
font: inherit;
}
.manual-edit-field textarea {
min-height: 110px;
resize: vertical;
line-height: 1.45;
}
.manual-edit-field.compact {
gap: 4px;
}
.manual-edit-field.compact input,
.manual-edit-field.compact select {
min-height: 32px;
padding: 6px 8px;
}
.manual-edit-code {
min-height: 150px;
font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace !important;
font-size: 11px !important;
white-space: pre;
}
.manual-edit-code.tall {
min-height: 260px;
}
.manual-edit-style-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 9px;
}
.manual-edit-style-grid .wide {
grid-column: 1 / -1;
}
.manual-edit-error {
margin: 0 12px 10px;
padding: 8px 10px;
border: 1px solid var(--red-border);
border-radius: 6px;
color: var(--red);
background: var(--red-bg);
font-size: 12px;
}
.manual-edit-actions {
display: flex;
justify-content: flex-end;
gap: 8px;
margin-top: auto;
padding: 12px;
border-top: 1px solid var(--border);
background: var(--bg-subtle);
}
.manual-edit-actions .primary {
color: var(--bg-panel);
border-color: var(--accent);
background: var(--accent);
}
.manual-edit-changes {
flex: 1;
min-height: 0;
overflow: hidden;
}
.manual-edit-history-actions {
display: flex;
gap: 6px;
padding: 0 10px 8px;
}
.manual-edit-history-entry {
display: grid;
gap: 6px;
padding: 9px;
border: 1px solid var(--border);
border-radius: 7px;
background: var(--bg);
}
.manual-edit-history-entry strong {
font-size: 12px;
}
.manual-edit-history-entry code {
overflow-wrap: anywhere;
color: var(--text-muted);
font-size: 11px;
white-space: pre-wrap;
}