        /* ════════════════════════════════════════════════════════════
           CHAT MODE  (Claude-style easy mode — class prefix `cm-`)
           Uses the same :root tokens as the Setup surface; only adds a
           serif display stack. A licensed OFL webfont (Newsreader /
           Spectral) can later be dropped in via @font-face overriding
           --serif with zero structural change.
           ════════════════════════════════════════════════════════════ */
        :root {
            --serif: "Iowan Old Style", "Palatino Linotype", "Palatino",
                     "Book Antiqua", Georgia, "Times New Roman", ui-serif, serif;
            --cm-rail: 56px;
            --cm-panel: 264px;
        }

        /* Fixed top-level mode toggle, floats over both surfaces. */
        .mode-slider {
            position: fixed;
            top: 14px;
            right: 18px;
            z-index: var(--z-dropdown);
            display: inline-flex;
            gap: 2px;
            padding: 3px;
            border-radius: 999px;
            background: var(--bg-card);
            border: 1px solid var(--border-strong);
            backdrop-filter: blur(8px);
        }
        .mode-slider button {
            appearance: none;
            border: 0;
            background: transparent;
            color: var(--text-dim);
            font: inherit;
            font-size: 12px;
            font-weight: 600;
            letter-spacing: 0.02em;
            padding: 5px 16px;
            border-radius: 999px;
            cursor: pointer;
            transition: color 0.15s, background 0.15s;
        }
        .mode-slider button:hover { color: var(--text); }
        .mode-slider button.active {
            color: var(--on-accent-warm);
            background: var(--accent-grad);
        }
        /* When the artifact panel is docked right, slide the Setup/Chat
           toggle left so it no longer sits on the panel's close button. */
        .mode-slider { transition: right 0.18s ease; }
        body.cm-panel-open .mode-slider { right: calc(46% + 16px); }
        body.chat-mode { overflow: hidden; }

        #chatRoot {
            position: fixed;
            inset: 0;
            display: flex;
            background: var(--bg);
            color: var(--text);
            font-size: 14px;
        }
        #chatRoot[hidden] { display: none; }

        /* Right-column wrapper: stacks the chat+artifact stage above a
           dedicated composer bar so the reply textbox spans the full
           content width regardless of whether the side panel is open.
           Without this the composer was bound to the chat column and
           shrank to ~54% the moment an artifact opened. */
        .cm-content {
            flex: 1;
            min-width: 0;
            display: flex;
            flex-direction: column;
        }
        .cm-stage {
            flex: 1;
            min-height: 0;
            display: flex;
            flex-direction: row;
        }
        .cm-composer-bar {
            flex: 0 0 auto;
            padding: 14px 24px 22px;
            border-top: 1px solid var(--border);
            background: var(--bg);
        }
        .cm-composer-bar:empty { display: none; }

        /* ── Sidebar ──────────────────────────────────────────────── */
        .cm-sidebar {
            flex: 0 0 var(--cm-rail);
            width: var(--cm-rail);
            display: flex;
            flex-direction: column;
            align-items: stretch;
            background: rgba(255, 255, 255, 0.015);
            border-right: 1px solid var(--border);
            transition: flex-basis 0.16s ease, width 0.16s ease;
            overflow: hidden;
        }
        .cm-sidebar.expanded { flex-basis: var(--cm-panel); width: var(--cm-panel); }
        .cm-side-top {
            display: flex;
            flex-direction: column;
            gap: 4px;
            padding: 12px 10px;
        }
        .cm-icon-btn {
            display: flex;
            align-items: center;
            gap: 12px;
            height: 36px;
            padding: 0 8px;
            border: 0;
            border-radius: 9px;
            background: transparent;
            color: var(--text-dim);
            font: inherit;
            font-size: 13px;
            cursor: pointer;
            white-space: nowrap;
            transition: background 0.13s, color 0.13s;
        }
        .cm-icon-btn:hover { background: var(--bg-card); color: var(--text); }
        .cm-icon-btn svg { flex: 0 0 20px; width: 20px; height: 20px; }
        .cm-icon-btn .cm-label { opacity: 0; transition: opacity 0.12s; }
        .cm-sidebar.expanded .cm-icon-btn .cm-label { opacity: 1; }
        .cm-icon-btn.cm-accent { color: var(--accent); }

        .cm-recents {
            flex: 1;
            min-height: 0;
            overflow-y: auto;
            padding: 6px 8px 8px;
            display: none;
        }
        .cm-sidebar.expanded .cm-recents { display: block; }
        /* position:relative anchors the trash button. We can't use flex here:
           ResonantJs's res-display toggles this element with an inline
           `display: inherit` (resonant.js), which clobbers `display: flex`
           and any inline-flow layout — so the trash is pinned via absolute
           positioning instead, immune to whatever display value res-display sets. */
        .cm-recents-head {
            position: relative;
            font-size: 10.5px;
            text-transform: uppercase;
            letter-spacing: 0.16em;
            color: var(--text-muted);
            padding: 10px 30px 6px 8px;
        }
        .cm-recents-head-label { display: block; }
        /* Hover-revealed group trash, pinned to the right of the header. Same
           fade-in pattern as .cm-conv-menu so the sidebar reads consistently. */
        .cm-recents-head-del {
            position: absolute;
            right: 4px;
            top: 50%;
            transform: translateY(-50%);
            opacity: 0;
            border: 0;
            background: transparent;
            color: var(--text-muted);
            cursor: pointer;
            padding: 3px 5px;
            border-radius: 5px;
            line-height: 0;
            transition: opacity 0.1s, color 0.1s, background 0.1s;
        }
        .cm-recents-head:hover .cm-recents-head-del { opacity: 0.8; }
        .cm-recents-head-del:hover {
            opacity: 1;
            color: var(--bad);
            background: rgba(248, 113, 113, 0.10);
        }
        .cm-recents-head-del svg { width: 13px; height: 13px; display: block; }

        /* Small "html" / "code" / "image" tag next to an artifact title in
           the sidebar's artifact view. Matches the conv-title's
           typography but mutes everything but the tag itself. */
        .cm-art-kind {
            display: inline-block;
            margin-left: 6px;
            padding: 1px 6px;
            border-radius: 4px;
            font-size: 10px;
            font-family: var(--mono);
            color: var(--text-muted);
            background: rgba(255, 255, 255, 0.05);
            border: 1px solid var(--border);
            text-transform: uppercase;
            letter-spacing: 0.04em;
            vertical-align: middle;
        }
        /* Per-artifact trash. Same hover reveal as cm-conv-menu but
           tinted red on hover so it reads as a destructive action. */
        .cm-conv-trash:hover { color: var(--bad); background: rgba(248, 113, 113, 0.10); }
        /* "vN ▾" version-count badge: an artifact edited in place collapses to
           one row; this badge exposes the chain depth and toggles the inline
           history below. Reads as a subtle, clickable accent chip. */
        .cm-art-vbadge {
            display: inline-block;
            margin-left: 6px;
            padding: 1px 6px;
            border-radius: 4px;
            font-size: 10px;
            font-family: var(--mono);
            color: var(--accent);
            background: var(--accent-soft);
            border: 1px solid var(--border);
            cursor: pointer;
            vertical-align: middle;
            letter-spacing: 0.02em;
        }
        .cm-art-vbadge:hover { filter: brightness(1.15); }
        .cm-art-vbadge.open { color: var(--text); }
        /* Inline version-history dropdown under an artifact row. Indented so it
           reads as belonging to the row above; one clickable line per version. */
        .cm-art-versions {
            margin: 2px 0 6px 14px;
            border-left: 1px solid var(--border);
            padding-left: 8px;
        }
        .cm-art-ver {
            display: flex;
            align-items: baseline;
            gap: 8px;
            padding: 4px 8px;
            border-radius: 6px;
            cursor: pointer;
            font-size: 12px;
            color: var(--text-dim);
        }
        .cm-art-ver:hover { background: var(--bg-card); color: var(--text); }
        .cm-art-ver-n { font-family: var(--mono); color: var(--accent); min-width: 24px; }
        .cm-art-ver-t { color: var(--text-muted); }
        .cm-art-ver-msg { cursor: default; color: var(--text-muted); }
        .cm-art-ver-msg:hover { background: transparent; color: var(--text-muted); }
        /* Sidebar toolbar button — show an "active" state when the
           Artifacts view is the current sidebar mode. The same .active
           treatment the New chat button uses. */
        .cm-icon-btn.active { color: var(--accent); background: var(--accent-soft); }
        .cm-conv {
            display: flex;
            align-items: center;
            gap: 6px;
            padding: 7px 9px;
            border-radius: 8px;
            color: var(--text-dim);
            cursor: pointer;
            font-size: 13px;
            white-space: nowrap;
            overflow: hidden;
        }
        .cm-conv:hover { background: var(--bg-card); color: var(--text); }
        .cm-conv.active { background: var(--accent-soft); color: var(--text); }
        .cm-conv-title { flex: 1; overflow: hidden; text-overflow: ellipsis; }
        .cm-conv-menu {
            opacity: 0;
            border: 0;
            background: transparent;
            color: var(--text-muted);
            cursor: pointer;
            padding: 2px 4px;
            border-radius: 5px;
            font-size: 15px;
            line-height: 1;
        }
        .cm-conv:hover .cm-conv-menu { opacity: 1; }
        .cm-conv-menu:hover { color: var(--text); background: var(--border-strong); }
        .cm-pin-dot { color: var(--accent); font-size: 10px; }

        .cm-side-foot {
            border-top: 1px solid var(--border);
            padding: 10px;
            display: flex;
            flex-direction: column;
            gap: 4px;
        }
        .cm-brand {
            display: flex;
            align-items: center;
            justify-content: center;
            padding: 6px 4px 2px;
        }
        /* Logo only (no wordmark) — small app glyph, expanded or collapsed. */
        .cm-brand .cm-star { width: 30px; height: 30px; }

        /* ── Main column ──────────────────────────────────────────── */
        .cm-main { flex: 1; display: flex; flex-direction: column; min-width: 0; position: relative; }
        .cm-topbar {
            height: 52px;
            flex: 0 0 52px;
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 0 70px 0 22px;
        }
        .cm-title-btn {
            display: inline-flex;
            align-items: center;
            gap: 7px;
            max-width: 60%;
            border: 0;
            background: transparent;
            color: var(--text);
            font: inherit;
            font-size: 14px;
            font-weight: 600;
            cursor: pointer;
            padding: 5px 9px;
            border-radius: 8px;
            overflow: hidden;
        }
        .cm-title-btn:hover { background: var(--bg-card); }
        .cm-title-btn span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
        .cm-title-btn svg { flex: 0 0 13px; width: 13px; height: 13px; opacity: 0.55; }

        /* Per-conversation Artifacts entry in the chat top bar. Sits
           next to the conversation title because artifacts belong to a
           specific chat — exposing them globally invites the question
           "for which chat?". */
        .cm-topbar-artifacts {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            border: 1px solid var(--border);
            background: transparent;
            color: var(--text-muted);
            font: inherit;
            font-size: 12px;
            font-weight: 500;
            cursor: pointer;
            padding: 5px 10px 5px 8px;
            border-radius: 8px;
            transition: color 0.1s, border-color 0.1s, background 0.1s;
        }
        .cm-topbar-artifacts:hover {
            color: var(--text);
            border-color: var(--border-strong);
            background: var(--bg-card);
        }
        .cm-topbar-artifacts.active {
            color: var(--accent);
            border-color: var(--accent);
            background: var(--accent-soft);
        }
        .cm-topbar-artifacts.is-empty { opacity: 0.55; }
        .cm-topbar-artifacts svg { width: 13px; height: 13px; }
        .cm-topbar-artifacts-label { white-space: nowrap; }
        /* Count badge on the right of the button. Empty when there are
           no artifacts (CSS :empty hides it so the button shrinks). */
        .cm-topbar-artifacts-count {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            min-width: 18px;
            height: 18px;
            padding: 0 5px;
            font-size: 10.5px;
            font-weight: 600;
            color: var(--accent);
            background: rgba(245, 144, 52, 0.14);
            border-radius: 999px;
            font-family: var(--mono);
        }
        .cm-topbar-artifacts-count:empty { display: none; }

        /* Sidebar artifacts list scope header — the user MUST see which
           conversation the list belongs to before they delete anything,
           so the chat title gets prime real estate. */
        .cm-art-scope-head {
            padding: 12px 10px 10px;
            border-bottom: 1px solid var(--border);
            margin-bottom: 6px;
        }
        .cm-art-scope-eyebrow {
            font-size: 10px;
            text-transform: uppercase;
            letter-spacing: 0.16em;
            color: var(--text-muted);
            margin-bottom: 2px;
        }
        .cm-art-scope-title {
            font-size: 13px;
            font-weight: 600;
            color: var(--text);
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            margin-bottom: 4px;
        }
        .cm-art-scope-count {
            font-size: 11px;
            color: var(--text-muted);
            font-family: var(--mono);
        }

        .cm-scroll { flex: 1; min-height: 0; overflow-y: auto; }
        .cm-scroll::-webkit-scrollbar { width: 10px; }
        .cm-scroll::-webkit-scrollbar-thumb {
            background: rgba(245, 144, 52, 0.15);
            border-radius: 10px;
            border: 3px solid transparent;
            background-clip: content-box;
        }

        /* ── Landing ──────────────────────────────────────────────── */
        .cm-landing {
            min-height: 100%;
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 40px 24px 96px;
            gap: 30px;
        }
        .cm-greet {
            display: flex;
            align-items: center;
            gap: 18px;
            font-family: var(--serif);
            font-size: 38px;
            font-weight: 500;
            letter-spacing: -0.01em;
            color: var(--text);
        }
        .cm-greet .cm-star { width: 38px; height: 38px; }
        .cm-star { color: var(--accent); display: inline-block; }
        .cm-star svg { width: 100%; height: 100%; display: block; }
        .cm-star.spin { animation: cmspin 9s linear infinite; }
        @keyframes cmspin { to { transform: rotate(360deg); } }
        .cm-star.pulse { animation: cmpulse 1.4s ease-in-out infinite; }
        @keyframes cmpulse { 0%,100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.55; transform: scale(0.9); } }

        .cm-starters {
            display: flex;
            flex-wrap: wrap;
            gap: 9px;
            justify-content: center;
            max-width: 720px;
        }
        .cm-chip {
            display: inline-flex;
            align-items: center;
            gap: 7px;
            padding: 8px 15px;
            border-radius: 999px;
            border: 1px solid var(--border-strong);
            background: transparent;
            color: var(--text-dim);
            font: inherit;
            font-size: 13px;
            cursor: pointer;
            transition: color 0.13s, border-color 0.13s, background 0.13s;
        }
        .cm-chip:hover { color: var(--text); border-color: var(--accent); background: var(--accent-soft); }
        .cm-chip svg { width: 15px; height: 15px; opacity: 0.8; }
        /* Extension chat-mode chips (e.g. Roleplay): entering a mode, not seeding
           the composer — tinted to set them apart from the built-in starters. */
        .cm-chip-mode { color: var(--text); border-color: var(--accent); background: var(--accent-soft); }
        .cm-chip-mode:hover { background: var(--accent); color: var(--on-accent, #fff); border-color: var(--accent); }

        /* ── Composer (shared by landing + conversation) ──────────── */
        .cm-composer-wrap { width: 100%; max-width: 760px; margin: 0 auto; }
        .cm-landing .cm-composer-wrap { max-width: 720px; }
        .cm-composer {
            background: var(--bg-card);
            border: 1px solid var(--border-strong);
            border-radius: 16px;
            padding: 14px 16px 10px;
            transition: border-color 0.15s;
            /* Positioning context for the gear-panel popover. */
            position: relative;
        }
        .cm-composer:focus-within { border-color: rgba(245, 144, 52, 0.45); }
        .cm-composer textarea {
            width: 100%;
            border: 0;
            outline: 0;
            resize: none;
            background: transparent;
            color: var(--text);
            font: inherit;
            font-size: 14.5px;
            line-height: 1.5;
            max-height: 220px;
            min-height: 24px;
        }
        .cm-composer textarea::placeholder { color: var(--text-muted); }
        .cm-composer-row {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-top: 8px;
            gap: 10px;
        }
        /* Gear button — the composer's single left-side control. Opens the
           chat-options panel (attach / model / per-chat tools). Same
           circular-icon shape as cm-send so the composer reads as:
           [gear] … [send]. */
        .cm-gear {
            width: 30px; height: 30px;
            border-radius: 999px;
            border: 1px solid var(--border-strong);
            background: transparent;
            color: var(--text-dim);
            cursor: pointer;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }
        .cm-gear svg { width: 15px; height: 15px; }
        .cm-gear:hover { color: var(--text); border-color: var(--accent); }

        /* Gear panel — chat options popover anchored above the composer. */
        .cm-gear-pop {
            position: absolute;
            bottom: calc(100% + 8px);
            left: 0;
            width: 300px;
            /* No overflow clipping here — the nested model popover anchors to
               the Model row and must escape the panel. The tools list below
               scrolls on its own instead. */
            background: var(--surface-pop, var(--bg-card));
            border: 1px solid var(--border-strong);
            border-radius: 12px;
            padding: 8px;
            box-shadow: 0 18px 40px rgba(0,0,0,0.5);
            z-index: var(--z-dropdown);
        }
        .cm-gear-sec {
            font-size: 10px;
            text-transform: uppercase;
            letter-spacing: 0.14em;
            color: var(--text-muted);
            padding: 10px 8px 4px;
        }
        .cm-gear-sec .cm-gear-sub { text-transform: none; letter-spacing: 0; opacity: 0.8; }
        .cm-gear-row {
            display: flex;
            align-items: center;
            gap: 8px;
            width: 100%;
            padding: 8px 8px;
            border: 0;
            border-radius: 8px;
            background: transparent;
            color: var(--text-dim);
            font: inherit;
            font-size: 13px;
            cursor: pointer;
            text-align: left;
        }
        .cm-gear-row:hover { background: var(--bg-card); color: var(--text); }
        .cm-gear-row:disabled { opacity: 0.5; cursor: default; }
        .cm-gear-ic { display: inline-flex; }
        .cm-gear-ic svg { width: 14px; height: 14px; }
        /* The model row reuses cm-model-pill (anchor for the model popover) —
           neutralize the pill's own shape inside the panel. */
        .cm-gear-pop .cm-model-pill { justify-content: space-between; }
        .cm-gear-pop .cm-model-pill b {
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .cm-gear-note { padding: 6px 8px; color: var(--text-muted); font-size: 12px; }
        .cm-gear-tools {
            padding-bottom: 2px;
            max-height: min(38vh, 280px);
            overflow-y: auto;
        }
        .cm-gear-group {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 6px 8px 2px;
            color: var(--text);
            font-size: 12.5px;
            font-weight: 600;
            cursor: pointer;
        }
        .cm-gear-group-tools { padding-left: 14px; }
        .cm-gear-tool {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 3px 8px;
            border-radius: 6px;
            color: var(--text-dim);
            font-size: 12.5px;
            cursor: pointer;
        }
        .cm-gear-tool:hover { background: var(--bg-card); color: var(--text); }
        .cm-gear-group input[type="checkbox"],
        .cm-gear-tool input[type="checkbox"] {
            accent-color: var(--accent);
            margin: 0;
            flex: 0 0 auto;
        }

        /* Staged-attachment chips above the composer. Each chip shows
           filename + size + a clear (×) button. Errored entries get a
           red border + a tooltip with the reason. */
        .cm-attachments {
            display: flex;
            flex-wrap: wrap;
            gap: 6px;
            margin-bottom: 8px;
        }
        .cm-att {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 4px 6px 4px 8px;
            border-radius: 999px;
            border: 1px solid var(--border-strong);
            background: var(--bg-card);
            color: var(--text);
            font-size: 11.5px;
            max-width: 240px;
        }
        .cm-att.err { border-color: rgba(248,113,113,0.6); color: var(--bad); }
        .cm-att-ic { display: inline-flex; color: var(--text-muted); }
        .cm-att-ic svg { width: 13px; height: 13px; }
        .cm-att-name {
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
            max-width: 140px;
        }
        .cm-att-sz { color: var(--text-muted); font-size: 10.5px; font-family: var(--mono); }
        .cm-att-x {
            border: 0;
            background: transparent;
            color: var(--text-muted);
            cursor: pointer;
            font-size: 14px;
            line-height: 1;
            padding: 0 4px;
            border-radius: 4px;
        }
        .cm-att-x:hover { color: var(--text); background: rgba(255,255,255,0.05); }

        .cm-composer-left { display: flex; align-items: center; gap: 8px; }
        .cm-composer-right { display: flex; align-items: center; gap: 10px; }
        .cm-model-pill {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 5px 11px;
            border-radius: 999px;
            border: 1px solid transparent;
            background: transparent;
            color: var(--text-dim);
            font: inherit;
            font-size: 12.5px;
            cursor: pointer;
            position: relative;
        }
        .cm-model-pill:hover { color: var(--text); background: var(--bg-card); border-color: var(--border-strong); }
        .cm-model-pill b { color: var(--text); font-weight: 600; }
        .cm-model-pill .cm-caret { opacity: 0.6; display: inline-flex; }
        .cm-model-pill svg { width: 12px; height: 12px; }
        .cm-conv-menu svg { width: 15px; height: 15px; display: block; }
        .cm-send {
            width: 32px; height: 32px;
            border-radius: 999px;
            border: 0;
            background: var(--accent-grad);
            color: var(--on-accent-warm);
            cursor: pointer;
            display: inline-flex;
            align-items: center;
            justify-content: center;
        }
        .cm-send:disabled { opacity: 0.4; cursor: default; }
        .cm-send.cm-stop { background: var(--bg-card); color: var(--bad); border: 1px solid rgba(248,113,113,0.4); }
        /* "New text" pill — shown while a stream is running and the user has
           scrolled up (auto-scroll paused), so arriving tokens are never
           invisible. Floats over the thread just above the composer bar;
           .cm-main is the positioning context. */
        .cm-jump-latest {
            position: absolute;
            bottom: 12px;
            left: 50%;
            transform: translateX(-50%);
            z-index: var(--z-dropdown);
            appearance: none;
            display: inline-flex;
            align-items: center;
            gap: 6px;
            padding: 6px 14px;
            border-radius: var(--radius-pill);
            border: 1px solid var(--border-strong);
            background: var(--surface-pop);
            color: var(--text-dim);
            font: inherit;
            font-size: 12px;
            font-weight: 600;
            cursor: pointer;
            box-shadow: var(--shadow-md);
            transition: color 0.15s, border-color 0.15s;
        }
        .cm-jump-latest:hover { color: var(--text); border-color: var(--accent); }
        .cm-jump-latest svg { width: 13px; height: 13px; }
        .cm-jump-latest[hidden] { display: none; }
        .cm-usage {
            display: inline-flex;
            align-items: center;
            gap: 6px;
            font-family: var(--mono);
            font-size: 11px;
            color: var(--text-muted);
            white-space: nowrap;
            cursor: default;
        }
        .cm-usage:empty { display: none; }
        .cm-usage b { color: var(--text-dim); font-weight: 600; }
        /* Context-fill bar in the composer pill. Width grows with the
           current cumulative token usage / model window. Width is
           inline-styled per render. */
        .cm-ctx-bar {
            display: inline-block;
            position: relative;
            width: 64px;
            height: 6px;
            border-radius: 999px;
            background: rgba(255,255,255,0.06);
            overflow: hidden;
        }
        .cm-ctx-bar > span {
            position: absolute;
            inset: 0;
            background: linear-gradient(90deg, var(--accent), var(--accent-deep));
            border-radius: 999px;
            transition: width 0.18s ease, background 0.18s ease;
        }
        /* As the window fills, shift the fill to amber (>75%) then red (>90%)
           so "context is running out" is obvious at a glance in both chat and
           code mode. */
        .cm-ctx-bar.warm > span { background: linear-gradient(90deg, #e0a83a, #c8862a); }
        .cm-ctx-bar.hot > span  { background: linear-gradient(90deg, #e5564b, #c8372e); }
        .cm-ctx-pct {
            display: inline-flex;
            align-items: baseline;
            gap: 4px;
            color: var(--text-dim);
        }
        .cm-ctx-pct b { color: var(--text); font-weight: 600; }
        .cm-ctx-num { color: var(--text-muted); font-size: 10.5px; }

        /* Per-turn context fill chip (sits next to the tokens chip in
           the action row). Hi-contrast variant of cm-act-tok so it
           reads as "this is the live context status, not just history". */
        .cm-act-ctx {
            color: var(--accent);
            border-color: rgba(245, 144, 52, 0.35);
            background: var(--accent-soft);
        }
        .cm-disclaimer {
            text-align: center;
            color: var(--text-muted);
            font-size: 11px;
            margin: 10px 0 14px;
        }

        /* Model dropdown popover */
        .cm-model-pop {
            position: absolute;
            bottom: calc(100% + 8px);
            right: 0;
            min-width: 280px;
            max-height: 320px;
            overflow-y: auto;
            background: var(--surface-pop);
            border: 1px solid var(--border-strong);
            border-radius: 12px;
            padding: 6px;
            box-shadow: 0 18px 40px rgba(0,0,0,0.5);
            z-index: var(--z-dropdown);
        }
        .cm-model-group {
            font-size: 10px;
            text-transform: uppercase;
            letter-spacing: 0.14em;
            color: var(--text-muted);
            padding: 8px 10px 4px;
        }
        .cm-model-opt {
            display: flex;
            align-items: center;
            gap: 8px;
            padding: 8px 10px;
            border-radius: 8px;
            cursor: pointer;
            color: var(--text-dim);
            font-size: 13px;
        }
        .cm-model-opt:hover { background: var(--bg-card); color: var(--text); }
        .cm-model-opt.sel { color: var(--text); box-shadow: inset 0 0 0 1px var(--good); }
        .cm-model-opt .cm-dot { width: 6px; height: 6px; border-radius: 999px; background: var(--text-muted); flex: 0 0 6px; }
        .cm-model-opt .cm-dot.ready { background: var(--good); }

        /* Local model + per-context picker */
        .cm-local-head { display: block; padding: 8px 10px 4px; }
        .cm-local-name { color: var(--text); font-size: 13px; font-weight: 600; }
        .cm-model-sub { color: var(--text-muted); font-size: 11px; margin-top: 2px; }
        .cm-est-tag { color: var(--warn); }
        .cm-ctx-row {
            display: flex; flex-wrap: wrap; gap: 6px;
            padding: 2px 10px 10px; border-bottom: 1px solid var(--border);
            margin-bottom: 4px;
        }
        .cm-ctx-chip {
            font: inherit; font-size: 11px; line-height: 1;
            padding: 6px 8px; border-radius: 7px; cursor: pointer;
            background: var(--bg-card); color: var(--text-dim);
            border: 1px solid var(--border-strong);
            transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
        }
        .cm-ctx-chip:hover { color: var(--text); border-color: var(--accent); }
        .cm-ctx-chip.ok { color: var(--good); border-color: rgba(74,222,128,0.35); }
        .cm-ctx-chip.ok.est { color: var(--text-dim); border-color: var(--border-strong); }
        .cm-ctx-chip.partial { color: var(--warn); border-color: rgba(251,191,36,0.35); }
        .cm-ctx-chip.no,
        .cm-ctx-chip.unknown { color: var(--text-muted); opacity: 0.75; }
        .cm-ctx-chip.sel {
            color: var(--text); font-weight: 600;
            border-color: var(--good);
            box-shadow: inset 0 0 0 1px var(--good);
        }

        /* ── Conversation ─────────────────────────────────────────── */
        .cm-thread {
            max-width: 760px;
            margin: 0 auto;
            padding: 16px 22px 4px;
            display: flex;
            flex-direction: column;
            gap: 26px;
        }
        .cm-turn { display: flex; flex-direction: column; }
        .cm-turn.user { align-items: flex-end; }
        .cm-user-bubble {
            background: #25364f;
            border: 1px solid #34507a;
            color: #e7eefb;
            padding: 11px 15px;
            border-radius: 14px 14px 4px 14px;
            max-width: 80%;
            white-space: pre-wrap;
            overflow-wrap: anywhere;
            line-height: 1.5;
        }
        /* Attached-image thumbnails sit under the user bubble, right-aligned
           to match the turn, reusing the .cm-art-thumb styling below. */
        .cm-user-images {
            display: flex;
            flex-wrap: wrap;
            justify-content: flex-end;
            gap: 8px;
            margin: 6px 0 2px;
            max-width: 80%;
        }
        .cm-asst { width: 100%; }
        /* ── Agentic action chain (one connected, collapsible unit) ── */
        .cm-chain {
            margin: 2px 0 14px;
            border: 1px solid var(--border);
            border-radius: 10px;
            background: var(--bg-card);
            overflow: hidden;
            /* Head row + collapsible body row, animated 0fr ⇄ 1fr. Unlike a
               max-height cap, this can never clip a long chain — the old
               1400px cap silently swallowed steps on big agentic runs. */
            display: grid;
            grid-template-rows: auto 0fr;
            transition: grid-template-rows 0.22s ease;
        }
        .cm-chain.open { grid-template-rows: auto 1fr; }
        .cm-chain-head {
            width: 100%;
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px 12px;
            border: 0;
            background: transparent;
            color: var(--text);
            font: inherit;
            font-size: 12.5px;
            cursor: pointer;
            text-align: left;
        }
        .cm-chain-head:hover { background: rgba(255,255,255,0.03); }
        .cm-chain-ic {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 16px; height: 16px;
            color: var(--good);
        }
        .cm-chain-ic svg { width: 15px; height: 15px; }
        .cm-chain.running .cm-chain-ic { color: var(--accent); }
        .cm-chain-bang { color: var(--bad); font-weight: 700; }
        .cm-chain-label { flex: 1; font-weight: 600; }
        .cm-chain.running .cm-chain-label { color: var(--text-dim); }
        .cm-chain-caret {
            display: inline-flex;
            color: var(--text-muted);
            transition: transform 0.16s ease;
        }
        .cm-chain-caret svg { width: 14px; height: 14px; }
        .cm-chain.open .cm-chain-caret { transform: rotate(180deg); }
        .cm-chain-body {
            position: relative;
            display: flex;
            flex-direction: column;
            gap: 4px;
            /* min-height:0 lets the grid row actually collapse (grid items
               default to min-height:auto). Vertical padding stays zero when
               collapsed, else it keeps ~14px of the body peeking out even
               at row height 0. */
            min-height: 0;
            padding: 0 12px 0 26px;
            overflow: hidden;
            transition: padding 0.22s ease;
        }
        .cm-chain.open .cm-chain-body {
            padding-top: 4px;
            padding-bottom: 12px;
        }
        /* Vertical connector tying the steps together as a chain. */
        .cm-chain-body::before {
            content: '';
            position: absolute;
            left: 19px;
            top: 4px;
            bottom: 16px;
            width: 2px;
            background: var(--border-strong);
        }
        .cm-tc-node {
            position: absolute;
            left: -11px;
            width: 9px; height: 9px;
            border-radius: 50%;
            background: var(--bg);
            border: 2px solid var(--border-strong);
        }
        .cm-chain-body .cm-toolcard.run .cm-tc-node { border-color: var(--accent); }
        .cm-chain-body .cm-toolcard.ok  .cm-tc-node { border-color: var(--good); background: var(--good); }
        .cm-chain-body .cm-toolcard.err .cm-tc-node { border-color: var(--bad); background: var(--bad); }
        .cm-chain-body .cm-toolcard {
            position: relative;
            border: 1px solid var(--border);
            border-left: 1px solid var(--border);
        }

        /* ── Sub-agent card ──
           A collapsible panel above the answer showing a delegated agent's
           live reasoning + answer. Same visual language as .cm-chain, with an
           accent left edge so it reads as "another agent's turn". */
        .cm-agentruns { display: flex; flex-direction: column; gap: 8px; margin: 2px 0 14px; }
        .cm-agent {
            border: 1px solid var(--border);
            border-left: 3px solid var(--accent);
            border-radius: 10px;
            background: var(--bg-card);
            overflow: hidden;
        }
        .cm-agent-head {
            width: 100%;
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 10px 12px;
            border: 0;
            background: transparent;
            color: var(--text);
            font: inherit;
            font-size: 12.5px;
            cursor: pointer;
            text-align: left;
        }
        .cm-agent-head:hover { background: rgba(255,255,255,0.03); }
        .cm-agent-ic {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            width: 16px; height: 16px;
            color: var(--good);
        }
        .cm-agent-ic svg { width: 15px; height: 15px; }
        .cm-agent.running .cm-agent-ic { color: var(--accent); }
        .cm-agent-label { flex: 1; font-weight: 600; }
        .cm-agent.running .cm-agent-label { color: var(--text-dim); }
        .cm-agent-head .cm-chain-caret { display: inline-flex; color: var(--text-muted); transition: transform 0.16s ease; }
        .cm-agent.open .cm-agent-head .cm-chain-caret { transform: rotate(180deg); }
        .cm-agent-body {
            max-height: 0;
            padding: 0 14px;
            overflow: hidden;
            transition: max-height 0.22s ease, padding 0.22s ease;
        }
        .cm-agent.open .cm-agent-body {
            max-height: 4000px;
            padding-top: 4px;
            padding-bottom: 12px;
            overflow: auto;
        }
        .cm-agent-think { margin: 0 0 8px; }
        .cm-agent-think-sum {
            border: 0; background: transparent; color: var(--text-muted);
            font: inherit; font-size: 11.5px; cursor: pointer; padding: 2px 0;
        }
        .cm-agent-think-sum::before { content: '▸ '; }
        .cm-agent-think.open .cm-agent-think-sum::before { content: '▾ '; }
        .cm-agent-think-body {
            display: none;
            white-space: pre-wrap;
            font-size: 11.5px;
            color: var(--text-dim);
            max-height: 220px;
            overflow: auto;
            margin-top: 4px;
            padding-left: 10px;
            border-left: 2px solid var(--border);
        }
        .cm-agent-think.open .cm-agent-think-body { display: block; }
        .cm-agent-steps { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 8px; }
        .cm-agent-steps:empty { display: none; }
        .cm-agent-step {
            font-size: 11px;
            padding: 2px 8px;
            border-radius: 999px;
            border: 1px solid var(--border);
            color: var(--text-dim);
        }
        .cm-agent-step.run { border-color: var(--accent); color: var(--accent); }
        .cm-agent-step.ok  { border-color: var(--good); color: var(--good); }
        .cm-agent-step.err { border-color: var(--bad); color: var(--bad); }
        .cm-agent-text { font-size: 13px; line-height: 1.55; }
        .cm-agent-err { color: var(--bad); font-size: 12px; margin-top: 6px; }

        /* Artifact panel: build badge + disabled header buttons. */
        .cm-ap-badge {
            font-size: 10.5px;
            color: var(--accent);
            background: var(--accent-soft);
            border: 1px solid rgba(245,144,52,0.4);
            padding: 1px 7px;
            border-radius: 999px;
            white-space: nowrap;
        }
        .cm-ap-btn:disabled { opacity: 0.35; cursor: default; }

        /* ── Agentic tool-activity cards + artifact chips ─────────── */
        .cm-toolcards { display: flex; flex-direction: column; gap: 6px; margin: 2px 0 14px; }
        .cm-toolcard {
            display: flex;
            align-items: center;
            gap: 10px;
            padding: 8px 12px;
            border: 1px solid var(--border);
            border-left: 2px solid var(--border-strong);
            border-radius: 8px;
            background: var(--bg-card);
            font-size: 12.5px;
        }
        .cm-toolcard.run { border-left-color: var(--accent); }
        .cm-toolcard.ok  { border-left-color: var(--good); }
        .cm-toolcard.err { border-left-color: var(--bad); }
        .cm-tc-ic { display: inline-flex; color: var(--text-dim); }
        .cm-tc-ic svg { width: 15px; height: 15px; }
        .cm-tc-main { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
        .cm-tc-main b { color: var(--text); font-weight: 600; }
        .cm-tc-det {
            color: var(--text-muted);
            font-family: var(--mono);
            font-size: 11px;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .cm-tc-st { display: inline-flex; align-items: center; min-width: 16px; justify-content: center; }
        .cm-tc-st svg { width: 14px; height: 14px; color: var(--good); }
        .cm-toolcard.err .cm-tc-st { color: var(--bad); font-weight: 700; }
        .cm-tc-spin {
            width: 12px; height: 12px;
            border: 2px solid var(--border-strong);
            border-top-color: var(--accent);
            border-radius: 999px;
            display: inline-block;
            animation: cm-spin 0.7s linear infinite;
        }
        @keyframes cm-spin { to { transform: rotate(360deg); } }
        .cm-artifacts { display: flex; flex-wrap: wrap; gap: 8px; margin: 4px 0 14px; }
        /* Live (interactive) artifact — a reactive module rendered inline. */
        .cm-live-artifact {
            flex: 1 1 100%;
            border: 1px solid var(--border-strong);
            border-radius: 12px;
            background: var(--bg-elevated, var(--bg-card));
            overflow: hidden;
        }
        .cm-live-head {
            display: flex;
            align-items: center;
            gap: 9px;
            padding: 8px 12px;
            border-bottom: 1px solid var(--border);
            background: var(--accent-soft);
        }
        .cm-live-dot {
            width: 7px; height: 7px; border-radius: 50%;
            background: var(--accent);
            box-shadow: 0 0 0 3px var(--accent-soft);
        }
        .cm-live-title { font-weight: 600; font-size: 13px; }
        .cm-live-tag {
            margin-left: auto;
            font-size: 10.5px; font-weight: 600; letter-spacing: 0.03em;
            text-transform: uppercase;
            color: var(--accent);
            opacity: 0.85;
        }
        /* Render the module on a LIGHT card — models style interactive content
           for a light/white surface (dark text, pale panels), which would be
           invisible on the dark chat theme. Matches the artifact-on-white look. */
        .cm-live-root {
            padding: 16px;
            background: var(--cm-live-bg, #f6f7f9);
            color: var(--cm-live-fg, #1a2230);
            border-bottom-left-radius: 12px;
            border-bottom-right-radius: 12px;
            font-family: -apple-system, "Segoe UI", system-ui, sans-serif;
            font-size: 14px;
            line-height: 1.5;
        }
        .cm-live-root a { color: #2563eb; }
        .cm-live-root canvas { max-width: 100%; }
        /* ── Live-module "house style" ─────────────────────────────────────
           A built-in base stylesheet so a module looks polished from PLAIN
           markup — the model shouldn't have to ship a big <style> block to get
           a clean input/button/list. Every rule uses :where() (ZERO specificity)
           so ANY style the model writes (inline or its own <style>) still wins;
           these are pure fallbacks. This also overrides the global dark chat
           theme's element rules so fields don't render dark on the light card.
           Utility classes (.lm-row/.lm-between/.lm-muted/.lm-primary/…) are
           documented in the create_live_artifact contract. KEEP IN SYNC with the
           standalone-doc copy in ArtifactStore._renderDoc (the pop-out path). */
        .cm-live-root :where(h1, h2, h3, h4) { margin: 0 0 12px; line-height: 1.25; font-weight: 700; }
        .cm-live-root :where(h2) { font-size: 20px; }
        .cm-live-root :where(h3) { font-size: 16px; }
        .cm-live-root :where(p) { margin: 0 0 10px; }
        .cm-live-root :where(label) { font-size: 14px; }
        .cm-live-root :where(hr) { border: none; border-top: 1px solid #e5e7eb; margin: 12px 0; }
        .cm-live-root :where(ul, ol) { margin: 0; padding: 0; list-style: none; }
        .cm-live-root :where(input, textarea, select, option, button) {
            background-color: #fff;
            color: #1a2230;
            font-family: inherit;
            font-size: 14px;
        }
        .cm-live-root :where(input, textarea, select) {
            padding: 8px 12px;
            border: 1px solid #ccc;
            border-radius: 8px;
            outline: none;
        }
        .cm-live-root :where(input:focus, textarea:focus, select:focus) {
            border-color: #4f46e5;
            box-shadow: 0 0 0 3px rgba(79, 70, 229, 0.15);
        }
        .cm-live-root :where(button) {
            padding: 8px 16px;
            border: 1px solid #d0d5dd;
            border-radius: 8px;
            font-weight: 600;
            cursor: pointer;
            transition: background 0.15s, border-color 0.15s;
        }
        .cm-live-root :where(button:hover) { background: #f3f4f6; }
        /* Opt-in component/utility classes the contract documents. */
        .cm-live-root :where(.lm-primary) { background: #4f46e5; color: #fff; border-color: #4f46e5; }
        .cm-live-root :where(.lm-primary:hover) { background: #4338ca; }
        .cm-live-root :where(.lm-ghost) { background: none; border: none; color: #6b7280; }
        .cm-live-root :where(.lm-ghost:hover) { background: #f3f4f6; color: #1a2230; }
        .cm-live-root :where(.lm-row) { display: flex; align-items: center; gap: 8px; }
        .cm-live-root :where(.lm-between) { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
        .cm-live-root :where(.lm-grow) { flex: 1; }
        .cm-live-root :where(.lm-muted) { color: #6b7280; font-size: 13px; }
        .cm-live-root :where(.lm-item) { display: flex; align-items: center; gap: 10px; padding: 10px 12px; border-bottom: 1px solid #eee; }
        .cm-live-root :where(.lm-card) { background: #fff; border: 1px solid #e5e7eb; border-radius: 12px; padding: 16px; }
        .cm-live-err {
            margin: 8px 0 0; padding: 8px 10px;
            background: rgba(248, 113, 113, 0.12);
            color: var(--bad, #f87171);
            border-radius: 8px;
            font: 12px ui-monospace, monospace;
            white-space: pre-wrap;
        }
        .cm-artifact {
            display: inline-flex;
            align-items: center;
            gap: 10px;
            padding: 9px 14px;
            border: 1px solid var(--border-strong);
            border-radius: 10px;
            background: var(--accent-soft);
            color: var(--text);
            cursor: pointer;
            text-align: left;
            font: inherit;
        }
        .cm-artifact:hover { border-color: var(--accent); }
        .cm-artifact .cm-tc-ic { color: var(--accent); }
        .cm-art-main { display: flex; flex-direction: column; gap: 1px; }
        .cm-art-main b { color: var(--text); font-weight: 600; font-size: 13px; }

        /* ── In-message image thumbnail ──────────────────────────────
           Image artifacts skip the chip shape and render as a real
           thumbnail inside the chat bubble. Click → openArtifactPanel
           dispatches to the image side panel for a full-size view. */
        .cm-art-thumb {
            display: inline-flex;
            flex-direction: column;
            gap: 8px;
            padding: 8px;
            border: 1px solid var(--border-strong);
            border-radius: 12px;
            background: var(--accent-soft);
            cursor: pointer;
            text-align: left;
            font: inherit;
            color: var(--text);
            max-width: 320px;
            transition: border-color 0.15s ease, transform 0.15s ease;
        }
        .cm-art-thumb:hover {
            border-color: var(--accent);
            transform: translateY(-1px);
        }
        .cm-art-thumb:active { transform: translateY(0); }

        .cm-art-thumb-frame {
            position: relative;
            width: 100%;
            min-height: 180px;
            border-radius: 8px;
            overflow: hidden;
            background: #0b1220;
            display: grid;
            place-items: center;
        }
        .cm-art-thumb-img {
            display: block;
            max-width: 100%;
            max-height: 360px;
            width: auto;
            height: auto;
            border-radius: 8px;
        }

        /* Loading skeleton — a soft, animated band so the chat row
           doesn't reflow when the bitmap arrives. */
        .cm-art-thumb-skel {
            position: absolute;
            inset: 0;
            background: linear-gradient(
                100deg,
                rgba(255,255,255,0.04) 30%,
                rgba(255,255,255,0.08) 50%,
                rgba(255,255,255,0.04) 70%);
            background-size: 200% 100%;
            animation: cm-art-skel 1.4s linear infinite;
        }
        @keyframes cm-art-skel {
            from { background-position: 200% 0; }
            to   { background-position: -200% 0; }
        }

        .cm-art-thumb-cap {
            display: flex;
            flex-direction: column;
            gap: 1px;
            padding: 0 4px 2px;
        }
        .cm-art-thumb-title {
            color: var(--text);
            font-weight: 600;
            font-size: 13px;
            line-height: 1.3;
            overflow: hidden;
            text-overflow: ellipsis;
            white-space: nowrap;
        }
        .cm-art-thumb-hint {
            color: var(--text-muted);
            font-size: 11px;
            line-height: 1.3;
        }

        /* ── Artifact side panel (docked right of the chat) ───────── */
        .cm-artifact-panel { display: none; }
        #chatRoot.cm-has-panel .cm-artifact-panel {
            display: flex;
            flex-direction: column;
            flex: 0 0 46%;
            min-width: 360px;
            max-width: 70%;
            border-left: 1px solid var(--border-strong);
            background: var(--bg);
        }
        .cm-ap-head {
            flex: 0 0 44px;
            display: flex;
            align-items: center;
            gap: 9px;
            padding: 0 10px 0 14px;
            border-bottom: 1px solid var(--border);
        }
        .cm-ap-ic { display: inline-flex; color: var(--accent); }
        .cm-ap-ic svg { width: 16px; height: 16px; }
        .cm-ap-title {
            flex: 1;
            min-width: 0;
            font-size: 12.5px;
            font-weight: 600;
            color: var(--text);
            white-space: nowrap;
            overflow: hidden;
            text-overflow: ellipsis;
        }
        .cm-ap-btn {
            width: 28px; height: 28px;
            display: inline-flex;
            align-items: center;
            justify-content: center;
            border: 0;
            border-radius: 7px;
            background: transparent;
            color: var(--text-dim);
            cursor: pointer;
        }
        .cm-ap-btn:hover { color: var(--text); background: var(--bg-card); }
        .cm-ap-btn svg { width: 15px; height: 15px; }
        /* Match the app's bg so the brief unstyled-document moment between
           srcdoc replacements (each streaming chunk for an artifact) blends
           into the panel instead of flashing white. The artifact's own
           document is free to paint over it once parsed; this is only the
           iframe-element fallback the user sees during the swap. */
        .cm-ap-frame {
            flex: 1;
            width: 100%;
            min-height: 0;
            border: 0;
            background: var(--bg);
        }

        /* Panel body host — flips between three layouts via data-layout:
             iframe → iframe full body (SVG/Markdown/Image/non-source HTML)
             monaco → Monaco editor full body (code artifacts)
             split  → editor on top, iframe preview on bottom (HTML)
           Children are sized via flex so swapping layout doesn't churn
           Monaco — its automaticLayout watches the host element. */
        .cm-ap-body {
            flex: 1;
            min-height: 0;
            display: flex;
            flex-direction: column;
            background: var(--bg);
        }
        .cm-ap-monaco {
            flex: 1;
            min-height: 0;
            min-width: 0;
            background: #1e1e1e;       /* matches Monaco's vs-dark canvas */
        }
        .cm-ap-body[data-layout="iframe"] .cm-ap-monaco { display: none; }
        .cm-ap-body[data-layout="monaco"] .cm-ap-frame { display: none; }
        .cm-ap-body[data-layout="split"] {
            /* Split view divides 55% to the live preview / 45% to the
               source editor — the preview is what the user is here for,
               but the editor needs enough room to scan more than two
               lines of HTML at a time. */
        }
        .cm-ap-body[data-layout="split"] .cm-ap-monaco {
            flex: 0 0 45%;
            border-bottom: 1px solid var(--border-strong);
        }
        .cm-ap-body[data-layout="split"] .cm-ap-frame { flex: 1; }

        .cm-asst-body {
            font-family: var(--serif);
            font-size: 16px;
            line-height: 1.72;
            color: #e9ecf4;
        }
        .cm-asst-body p { margin: 0 0 14px; }
        .cm-asst-body h1, .cm-asst-body h2, .cm-asst-body h3, .cm-asst-body h4 {
            font-family: var(--serif);
            font-weight: 600;
            line-height: 1.3;
            margin: 22px 0 10px;
        }
        .cm-asst-body h1 { font-size: 24px; }
        .cm-asst-body h2 { font-size: 20px; }
        .cm-asst-body h3 { font-size: 17px; }
        .cm-asst-body ul, .cm-asst-body ol { margin: 0 0 14px; padding-left: 22px; }
        .cm-asst-body li { margin: 4px 0; }
        .cm-asst-body a { color: var(--accent); text-decoration: none; }
        .cm-asst-body a:hover { text-decoration: underline; }
        .cm-asst-body blockquote {
            margin: 0 0 14px;
            padding: 4px 16px;
            border-left: 3px solid var(--border-strong);
            color: var(--text-dim);
        }
        .cm-asst-body code {
            font-family: var(--mono);
            font-size: 0.86em;
            background: var(--code-bg);
            padding: 2px 6px;
            border-radius: 5px;
        }
        .cm-asst-body pre {
            background: var(--code-bg);
            border: 1px solid var(--border);
            border-radius: 10px;
            padding: 14px 16px;
            overflow-x: auto;
            margin: 0 0 16px;
        }
        .cm-asst-body pre code {
            font-family: var(--mono);
            font-size: 12.5px;
            line-height: 1.6;
            background: transparent;
            padding: 0;
            color: #d6dbe6;
        }
        .cm-asst-body table {
            border-collapse: collapse;
            margin: 0 0 16px;
            font-family: var(--mono);
            font-size: 12.5px;
            display: block;
            overflow-x: auto;
        }
        .cm-asst-body th, .cm-asst-body td {
            border: 1px solid var(--border);
            padding: 6px 12px;
            text-align: left;
        }
        .cm-asst-body th { background: var(--bg-card); color: var(--text); }
        /* Compact built-in highlighter token classes */
        .cm-tk-kw  { color: #c792ea; }
        .cm-tk-str { color: #c3e88d; }
        .cm-tk-num { color: #f78c6c; }
        .cm-tk-com { color: #5d6680; font-style: italic; }
        .cm-tk-fn  { color: #82aaff; }
        .cm-tk-pun { color: #89ddff; }

        /* Custom disclosure (not native <details>) so open AND close
           both animate — a native toggle slams shut, which the user
           found jarring. Closed = max-height/padding collapse to 0. */
        .cm-think {
            margin: 0 0 14px;
            border: 1px solid rgba(116, 176, 255, 0.2);
            background: rgba(116, 176, 255, 0.04);
            border-radius: 10px;
            overflow: hidden;
        }
        .cm-think-sum {
            display: flex;
            align-items: center;
            width: 100%;
            text-align: left;
            border: 0;
            background: transparent;
            cursor: pointer;
            padding: 8px 13px;
            font: inherit;
            font-size: 12px;
            color: #9fb0c8;
            user-select: none;
        }
        .cm-think-sum::before {
            content: "\25B8";
            margin-right: 8px;
            transition: transform 0.2s ease;
        }
        .cm-think.open .cm-think-sum::before { transform: rotate(90deg); }
        .cm-think-body {
            max-height: 0;
            padding: 0 13px;
            opacity: 0.5;
            overflow: hidden;
            font-size: 12.5px;
            color: #9fb0c8;
            white-space: pre-wrap;
            transition: max-height 0.28s ease, padding 0.28s ease, opacity 0.2s ease;
        }
        .cm-think.open .cm-think-body {
            max-height: 350px;
            padding: 2px 13px 11px;
            opacity: 1;
            overflow-y: auto;
        }

        .cm-actions {
            display: flex;
            gap: 4px;
            margin-top: 10px;
            opacity: 0;
            transition: opacity 0.13s;
        }
        .cm-asst:hover .cm-actions, .cm-actions.show { opacity: 1; }
        .cm-act {
            border: 0;
            background: transparent;
            color: var(--text-muted);
            cursor: pointer;
            padding: 5px;
            border-radius: 6px;
            display: inline-flex;
        }
        .cm-act:hover { color: var(--text); background: var(--bg-card); }
        .cm-act svg { width: 15px; height: 15px; }
        .cm-act.done { color: var(--good); }
        .cm-act:disabled { opacity: 0.3; cursor: default; }
        .cm-variants {
            display: inline-flex;
            align-items: center;
            gap: 2px;
            margin-left: 6px;
            padding-left: 8px;
            border-left: 1px solid var(--border);
        }
        .cm-variants .cm-act { font-size: 15px; line-height: 1; padding: 4px 7px; }

        /* Per-turn token stamp. Sits in its OWN row beside the action
           row so it's always visible (the action row still fades in on
           hover) — old conversations show turn-by-turn token cost at a
           glance without copy/retry buttons forced into the foreground. */
        .cm-meta-row {
            display: flex;
            align-items: center;
            gap: 8px;
            margin-top: 6px;
            min-height: 22px;
        }
        .cm-act-tok {
            font-size: 11px;
            color: var(--text-muted);
            font-family: var(--mono);
            white-space: nowrap;
            padding: 3px 9px;
            border-radius: 999px;
            background: var(--bg-card);
            border: 1px solid var(--border);
        }
        /* Server-reported prompt + generation tok/s. Lives INSIDE the
           action row next to copy/regenerate, so it inherits the same
           fade-on-hover treatment as the buttons. Tighter chrome than
           the meta-row token pill — no border, just colour, since the
           buttons around it are also borderless. */
        .cm-act-speed {
            font-size: 11px;
            color: var(--accent, #f59034);
            font-family: var(--mono);
            white-space: nowrap;
            padding: 4px 8px;
            border-radius: 6px;
            background: rgba(245, 144, 52, 0.08);
            margin-left: 2px;
        }
        .cm-var-lbl {
            font-size: 11px;
            color: var(--text-muted);
            font-family: var(--mono);
            min-width: 34px;
            text-align: center;
        }

        .cm-error {
            color: var(--bad);
            font-size: 13px;
            border: 1px solid rgba(248,113,113,0.3);
            background: rgba(248,113,113,0.06);
            border-radius: 8px;
            padding: 9px 13px;
            margin-top: 8px;
        }

        /* One-click fix offered under a recoverable error (e.g. download a
           missing runtime, then auto-retry the turn). */
        .cm-fix {
            display: flex;
            align-items: center;
            flex-wrap: wrap;
            gap: 10px;
            margin-top: 8px;
        }
        .cm-fix-btn {
            display: inline-flex;
            align-items: center;
            gap: 7px;
            padding: 7px 13px;
            border-radius: 8px;
            border: 1px solid var(--accent);
            background: var(--accent);
            color: #fff;
            font-size: 13px;
            font-weight: 600;
            cursor: pointer;
        }
        .cm-fix-btn:hover { filter: brightness(1.07); }
        .cm-fix-btn:disabled, .cm-fix-btn.busy {
            opacity: 0.6;
            cursor: default;
        }
        .cm-fix-btn svg { width: 15px; height: 15px; }
        .cm-fix-status {
            font-size: 12.5px;
            color: var(--text-muted);
            font-family: var(--mono);
        }
        .cm-fix-note {
            font-size: 12.5px;
            color: var(--text-muted);
        }
        .cm-thread-foot { height: 8px; }

        /* Tiny context menu (rename/delete/pin) */
        .cm-menu {
            position: fixed;
            z-index: var(--z-dropdown);
            min-width: 160px;
            background: var(--surface-pop);
            border: 1px solid var(--border-strong);
            border-radius: 10px;
            padding: 5px;
            box-shadow: 0 16px 36px rgba(0,0,0,0.5);
        }
        .cm-menu button {
            display: flex;
            width: 100%;
            align-items: center;
            gap: 9px;
            border: 0;
            background: transparent;
            color: var(--text-dim);
            font: inherit;
            font-size: 13px;
            padding: 8px 10px;
            border-radius: 7px;
            cursor: pointer;
            text-align: left;
        }
        .cm-menu button svg { flex: 0 0 15px; width: 15px; height: 15px; opacity: 0.7; }
        .cm-menu button:hover { background: var(--bg-card); color: var(--text); }
        .cm-menu button.danger:hover { color: var(--bad); }

        .cm-search-box {
            margin: 8px;
            display: none;
        }
        .cm-sidebar.expanded .cm-search-box.on { display: block; }
        .cm-search-box input {
            width: 100%;
            box-sizing: border-box;
            background: var(--bg-card);
            border: 1px solid var(--border-strong);
            border-radius: 8px;
            color: var(--text);
            font: inherit;
            font-size: 13px;
            padding: 7px 10px;
            outline: 0;
        }
        .cm-search-box input:focus { border-color: var(--accent); }
        .cm-empty { color: var(--text-muted); font-size: 12.5px; padding: 14px 10px; text-align: center; }

        /* Custom prompt modal — Electron's renderer has no window.prompt(). */
        .cm-modal-back {
            position: fixed;
            inset: 0;
            z-index: var(--z-modal);
            background: rgba(4, 8, 16, 0.6);
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .cm-modal {
            width: 380px;
            max-width: calc(100vw - 40px);
            background: var(--surface-pop);
            border: 1px solid var(--border-strong);
            border-radius: 14px;
            padding: 20px;
            box-shadow: 0 24px 60px rgba(0, 0, 0, 0.55);
        }
        .cm-modal-title {
            font-size: 14px;
            font-weight: 600;
            color: var(--text);
            margin-bottom: 12px;
        }
        .cm-modal-msg {
            font-size: 14px;
            line-height: 1.5;
            color: var(--text-dim);
        }
        .cm-modal-input {
            width: 100%;
            box-sizing: border-box;
            background: var(--bg);
            border: 1px solid var(--border-strong);
            border-radius: 8px;
            color: var(--text);
            font: inherit;
            font-size: 14px;
            padding: 9px 11px;
            outline: 0;
        }
        .cm-modal-input:focus { border-color: var(--accent); }
        .cm-modal-actions {
            display: flex;
            justify-content: flex-end;
            gap: 8px;
            margin-top: 16px;
        }
        .cm-modal-btn {
            border: 1px solid var(--border-strong);
            background: transparent;
            color: var(--text-dim);
            font: inherit;
            font-size: 13px;
            font-weight: 600;
            padding: 7px 16px;
            border-radius: 999px;
            cursor: pointer;
        }
        .cm-modal-btn:hover { color: var(--text); border-color: var(--accent); }
        .cm-modal-btn.primary {
            border-color: transparent;
            color: var(--on-accent-warm);
            background: var(--accent-grad);
        }
        .cm-modal-btn.danger {
            border-color: transparent;
            color: #fff;
            background: var(--bad);
        }
        .cm-modal-btn.danger:hover { color: #fff; border-color: transparent; filter: brightness(1.08); }

        /* ── Extension chat-mode picker (New chat) ── */
        .cm-mode-picker { width: 560px; }
        .cm-mode-grid {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 12px;
            margin: 6px 0 4px;
        }
        .cm-mode-card {
            display: flex;
            flex-direction: column;
            gap: 6px;
            text-align: left;
            padding: 16px;
            border: 1px solid var(--border-strong);
            border-radius: 12px;
            background: rgba(255, 255, 255, 0.03);
            color: var(--text);
            cursor: pointer;
        }
        .cm-mode-card:hover { border-color: var(--accent); background: rgba(245, 144, 52, 0.08); }
        .cm-mode-ic { font-size: 22px; line-height: 1; }
        .cm-mode-name { font-weight: 600; font-size: 14px; }
        .cm-mode-desc { font-size: 12px; color: var(--text-dim); }
        .cm-preflight-list {
            margin: 6px 0 4px;
            padding-left: 18px;
            color: var(--text-dim);
            font-size: 13px;
            line-height: 1.5;
        }

        /* ── Per-conversation mode background (theming hook) ──
           A mode (e.g. roleplay scenes) sets --cm-bg-image; the image sits
           behind the chat with a darkening overlay so message text stays
           legible. Content is lifted above both pseudo-layers. */
        .cm-main.cm-has-bg::before {
            content: '';
            position: absolute;
            inset: 0;
            z-index: 0;
            pointer-events: none;
            background-image: var(--cm-bg-image);
            background-size: cover;
            background-position: center;
            opacity: 0.5;
            transition: background-image 0.4s ease;
        }
        .cm-main.cm-has-bg::after {
            content: '';
            position: absolute;
            inset: 0;
            z-index: 0;
            pointer-events: none;
            background: linear-gradient(180deg, rgba(11, 18, 32, 0.55), rgba(11, 18, 32, 0.80));
        }
        .cm-main.cm-has-bg > * { position: relative; z-index: 1; }
        /* …except the jump pill, which must keep floating over the thread. */
        .cm-main.cm-has-bg > .cm-jump-latest { position: absolute; z-index: var(--z-dropdown); }
