/* =============================================================
   ChatMMM App Shell
   Grid: [sidebar | topbar+main] with sticky regions.
   Lives in the `components` layer so token swaps still cascade.
   ============================================================= */

@layer components {

    /* The hidden attribute must always beat component display rules
       (e.g. .cmm-nav-item{display:flex}) - without this, every JS-gated
       element (pro-only nav, guest CTAs, popovers) renders despite
       el.setAttribute('hidden'). */
    body.cmm-app [hidden] { display: none !important; }

    /* ---------- Body baseline for app-shell pages ---------- */
    body.cmm-app {
        font-family: var(--font-sans);
        font-size: var(--fs-base);
        line-height: var(--lh-normal);
        color: var(--text-primary, #0f172a);
        background: var(--surface-sunken);
        margin: 0;
        min-height: 100vh;
        scrollbar-gutter: stable;
        text-rendering: optimizeLegibility;
        -webkit-font-smoothing: antialiased;
    }

    /* ---------- Outer grid ---------- */
    .cmm-shell {
        display: grid;
        grid-template-columns: var(--sidebar-w) 1fr;
        grid-template-rows: var(--topbar-h) 1fr;
        grid-template-areas:
            "sidebar topbar"
            "sidebar main";
        min-height: 100vh;
        transition: grid-template-columns var(--dur-base) var(--ease-out-soft);
    }

    .cmm-shell.cmm-shell--collapsed {
        grid-template-columns: var(--sidebar-w-collapsed) 1fr;
    }

    /* ---------- Sidebar ---------- */
    .cmm-sidebar {
        grid-area: sidebar;
        /* Fixed so hover-expansion overlays main content (no reflow). The
           grid still reserves a track at --sidebar-w(-collapsed), which the
           sidebar visually fills at rest. Hover expands width only. */
        position: fixed;
        top: 0;
        left: 0;
        width: var(--sidebar-w);
        height: 100vh;
        background: var(--surface-card);
        border-right: 1px solid var(--border-color, #e5e7eb);
        z-index: var(--z-sidebar);
        display: flex;
        flex-direction: column;
        /* overflow visible so the floating collapse pill isn't clipped.
           Inner regions (brand, nav) handle their own clipping. */
        overflow: visible;
        will-change: width;
        transition:
            width var(--dur-base) var(--ease-out-soft),
            box-shadow var(--dur-base) var(--ease-out-soft),
            background var(--dur-base) var(--ease-out);
    }

    .cmm-shell--collapsed .cmm-sidebar {
        width: var(--sidebar-w-collapsed);
    }

    .cmm-sidebar__brand {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 14px 18px;
        height: var(--topbar-h);
        border-bottom: 1px solid var(--border-color, #e5e7eb);
        white-space: nowrap;
        overflow: hidden;
    }
    .cmm-sidebar__brand-mark {
        width: 32px;
        height: 32px;
        border-radius: 9px;
        background: linear-gradient(135deg, var(--brand-500), var(--brand-700));
        color: #fff;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-weight: 800;
        font-size: 14px;
        flex-shrink: 0;
        overflow: hidden;
        box-shadow: var(--elev-2);
    }
    /* When the logo image loads it fills the tile; if it 404s, onerror swaps in
       the "C" fallback (cmm-sidebar__brand-mark--text keeps the gradient look). */
    .cmm-sidebar__brand-img {
        width: 100%;
        height: 100%;
        object-fit: cover;
        display: block;
    }

    /* When the real logo image is present, sit it on a clean white chip so the
       (transparent) Swrl mark reads on any theme. The "C" text fallback below
       keeps the purple gradient via .cmm-sidebar__brand-mark--text. */
    .cmm-sidebar__brand-mark:not(.cmm-sidebar__brand-mark--text) {
        background: #ffffff;
    }
    .cmm-sidebar__brand-mark--text {
        background: linear-gradient(135deg, var(--brand-500), var(--brand-700));
    }
    .cmm-sidebar__brand-name {
        font-weight: 700;
        letter-spacing: -0.01em;
        font-size: 15px;
        color: var(--text-primary);
        opacity: 1;
        transition: opacity var(--dur-fast) var(--ease-out);
    }
    .cmm-shell--collapsed .cmm-sidebar__brand-name {
        opacity: 0;
        pointer-events: none;
    }

    .cmm-sidebar__nav {
        flex: 1;
        padding: 12px 10px;
        overflow-y: auto;
        overflow-x: hidden;
        scrollbar-gutter: stable;
        transition: scrollbar-color var(--dur-base) var(--ease-out);
    }
    .cmm-sidebar__nav::-webkit-scrollbar { width: 6px; }
    .cmm-sidebar__nav::-webkit-scrollbar-thumb {
        background: var(--color-gray-300, #d1d5db);
        border-radius: 3px;
    }
    /* Hide scrollbar entirely while in rail mode (no overflow expected for 7 items). */
    .cmm-shell--collapsed .cmm-sidebar__nav {
        overflow-y: hidden;
        scrollbar-width: none;
    }
    .cmm-shell--collapsed .cmm-sidebar__nav::-webkit-scrollbar { display: none; }

    .cmm-sidebar__section {
        margin: 10px 0 6px;
        padding: 0 12px;
        font-size: var(--fs-xs);
        font-weight: 600;
        text-transform: uppercase;
        letter-spacing: var(--tracking-caps);
        color: var(--text-muted, #6b7280);
        opacity: 1;
        transition: opacity var(--dur-fast) var(--ease-out);
    }
    .cmm-shell--collapsed .cmm-sidebar__section {
        opacity: 0;
        pointer-events: none;
    }

    .cmm-nav-item {
        position: relative;
        display: flex;
        align-items: center;
        gap: 12px;
        padding: 10px 12px;
        margin: 2px 0;
        border-radius: 10px;
        color: var(--text-secondary, #4b5563);
        text-decoration: none;
        font-weight: 500;
        font-size: var(--fs-sm);
        white-space: nowrap;
        /* overflow stays visible so the active-state left bar can render
           outside the rounded corner. The label has its own overflow/ellipsis. */
        transition:
            background var(--dur-fast) var(--ease-out),
            color var(--dur-fast) var(--ease-out),
            transform var(--dur-fast) var(--ease-out);
    }
    /* When a <button> is used as a nav item (e.g. theme toggle), strip
       user-agent button styling so it visually matches anchor nav items. */
    button.cmm-nav-item,
    .cmm-nav-item--button {
        width: 100%;
        border: none;
        background: transparent;
        font: inherit;
        text-align: left;
        cursor: pointer;
    }
    .cmm-nav-item__icon {
        width: 20px;
        text-align: center;
        flex-shrink: 0;
        font-size: 15px;
        color: var(--text-muted, #6b7280);
        transition: color var(--dur-fast) var(--ease-out);
    }
    .cmm-nav-item__label {
        flex: 1;
        overflow: hidden;
        text-overflow: ellipsis;
        opacity: 1;
        transition: opacity var(--dur-fast) var(--ease-out);
    }
    .cmm-nav-item__badge {
        font-size: 11px;
        font-weight: 700;
        padding: 2px 7px;
        border-radius: 999px;
        background: var(--brand-100);
        color: var(--brand-700);
        flex-shrink: 0;
        opacity: 1;
        transition: opacity var(--dur-fast) var(--ease-out);
    }
    .cmm-nav-item:hover {
        background: var(--surface-sunken);
        color: var(--text-primary);
    }
    .cmm-nav-item:hover .cmm-nav-item__icon {
        color: var(--brand-600);
    }
    .cmm-nav-item:active {
        transform: translateX(1px);
    }
    .cmm-nav-item:focus-visible {
        outline: none;
        box-shadow: var(--elev-glow-brand);
        background: var(--brand-50);
    }

    /* Active state - violet fill + left bar (Image 2 pattern) */
    .cmm-nav-item.is-active,
    .cmm-nav-item[aria-current="page"] {
        background: var(--brand-50);
        color: var(--brand-700);
        font-weight: 600;
    }
    .cmm-nav-item.is-active .cmm-nav-item__icon,
    .cmm-nav-item[aria-current="page"] .cmm-nav-item__icon {
        color: var(--brand-600);
    }
    .cmm-nav-item.is-active::before,
    .cmm-nav-item[aria-current="page"]::before {
        content: "";
        position: absolute;
        left: -10px;
        top: 8px;
        bottom: 8px;
        width: 3px;
        border-radius: 0 3px 3px 0;
        background: var(--brand-600);
        transition: transform var(--dur-base) var(--ease-out-soft),
                    opacity var(--dur-fast) var(--ease-out);
        transform-origin: left center;
    }
    /* Collapse animates the bar into a dot-like nub in rail mode. */
    .cmm-shell--collapsed .cmm-nav-item.is-active::before,
    .cmm-shell--collapsed .cmm-nav-item[aria-current="page"]::before {
        transform: scaleY(0.55);
    }

    .cmm-shell--collapsed .cmm-nav-item__label,
    .cmm-shell--collapsed .cmm-nav-item__badge {
        opacity: 0;
        pointer-events: none;
    }
    /* User-card meta uses the same fade pattern. */
    .cmm-user-card__meta {
        transition: opacity var(--dur-fast) var(--ease-out);
    }
    .cmm-shell--collapsed .cmm-user-card__meta {
        opacity: 0;
        pointer-events: none;
    }

    .cmm-sidebar__footer {
        border-top: 1px solid var(--border-color, #e5e7eb);
        padding: 10px;
    }
    .cmm-user-card {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 8px 10px;
        border-radius: 10px;
        cursor: pointer;
        transition: background var(--dur-fast) var(--ease-out);
    }
    .cmm-user-card:hover {
        background: var(--surface-sunken);
    }
    .cmm-user-card__avatar {
        width: 36px;
        height: 36px;
        border-radius: 50%;
        background: linear-gradient(135deg, var(--brand-400), var(--brand-700));
        color: #fff;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-weight: 700;
        font-size: 14px;
        flex-shrink: 0;
    }
    .cmm-user-card__meta {
        flex: 1;
        min-width: 0;
        line-height: 1.2;
    }
    .cmm-user-card__name {
        font-weight: 600;
        font-size: var(--fs-sm);
        color: var(--text-primary);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .cmm-user-card__plan {
        font-size: var(--fs-xs);
        color: var(--text-muted, #6b7280);
        margin-top: 3px;
    }
    /* Shared gold "Pro" badge — sidebar user card + the Prominent Signals
       (Pro-exclusive) strip header. Self-contained (own color/bg) so it reads
       the same on light and dark themes. Dark amber text on bright gold reads as
       a premium "gold foil" pill and clears WCAG AA (~4.7:1+) where white did not. */
    .cmm-pro-badge {
        display: inline-flex;
        align-items: center;
        font-size: 10px;
        font-weight: 800;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: #451a03;
        background: linear-gradient(135deg, #f59e0b, #d97706);
        padding: 2px 8px;
        border-radius: 999px;
        line-height: 1.4;
        box-shadow: 0 1px 3px rgba(217, 119, 6, 0.35);
    }
    /* User card is a <button> now (opens the account menu) - reset button chrome. */
    button.cmm-user-card {
        width: 100%;
        border: none;
        font: inherit;
        text-align: left;
        color: inherit;
    }
    .cmm-user-card__caret {
        margin-left: auto;
        font-size: 11px;
        color: var(--text-muted);
        transition: transform var(--dur-fast, 0.15s) var(--ease-out, ease);
    }
    .cmm-user-card[aria-expanded="true"] .cmm-user-card__caret { transform: rotate(180deg); }
    .cmm-shell--collapsed .cmm-user-card__caret { display: none; }

    /* Account menu (pops up from the user card). */
    .cmm-sidebar__footer { position: relative; }
    .cmm-user-menu {
        position: absolute;
        left: 10px;
        right: 10px;
        min-width: 180px;          /* stays readable when the sidebar is collapsed (rail) */
        bottom: calc(100% - 4px);
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        border-radius: 10px;
        box-shadow: var(--elev-3, 0 16px 40px rgba(0, 0, 0, 0.28));
        padding: 6px;
        display: flex;
        flex-direction: column;
        gap: 2px;
        z-index: 50;
    }
    .cmm-user-menu[hidden] { display: none; }
    .cmm-user-menu__item {
        display: flex;
        align-items: center;
        gap: 10px;
        width: 100%;
        padding: 9px 10px;
        border: none;
        background: transparent;
        border-radius: 8px;
        font: inherit;
        font-size: var(--fs-sm, 0.9rem);
        color: var(--text-primary);
        text-align: left;
        cursor: pointer;
        text-decoration: none;
        transition: background var(--dur-fast, 0.15s) var(--ease-out, ease);
    }
    .cmm-user-menu__item i { width: 16px; text-align: center; color: var(--text-muted); }
    .cmm-user-menu__item:hover { background: var(--surface-sunken, color-mix(in srgb, var(--brand-700) 8%, transparent)); }
    .cmm-user-menu__item--danger { color: #dc2626; }
    .cmm-user-menu__item--danger i { color: #dc2626; }
    .cmm-user-menu__item--danger:hover { background: color-mix(in srgb, #ef4444 12%, transparent); }

    /* Reusable loading spinner (data-loading states across pages). */
    .cmm-spinner {
        display: inline-block;
        width: 18px;
        height: 18px;
        border: 2px solid color-mix(in srgb, var(--brand-700) 22%, transparent);
        border-top-color: var(--brand-700);
        border-radius: 50%;
        animation: cmm-spin 0.7s linear infinite;
        vertical-align: middle;
    }
    .cmm-spinner--lg { width: 30px; height: 30px; border-width: 3px; }
    .cmm-loading-cell {
        padding: 28px 16px;
        text-align: center;
        color: var(--text-muted);
        font-size: var(--fs-sm, 0.9rem);
    }
    .cmm-loading-cell .cmm-spinner { margin-right: 8px; }
    @keyframes cmm-spin { to { transform: rotate(360deg); } }
    @media (prefers-reduced-motion: reduce) {
        .cmm-spinner { animation-duration: 1.5s; }
    }

    .cmm-sidebar__collapse {
        position: absolute;
        top: 14px;
        right: -10px;
        width: 22px;
        height: 22px;
        border-radius: 50%;
        background: var(--surface-card);
        border: 1px solid var(--border-color, #e5e7eb);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        cursor: pointer;
        color: var(--text-muted);
        font-size: 11px;
        box-shadow: var(--elev-1);
        z-index: 2;
        transition: transform var(--dur-base) var(--ease-out-soft),
                    color var(--dur-fast) var(--ease-out),
                    background var(--dur-fast) var(--ease-out),
                    border-color var(--dur-fast) var(--ease-out),
                    box-shadow var(--dur-fast) var(--ease-out);
    }
    .cmm-sidebar__collapse:hover {
        color: var(--brand-600);
        border-color: var(--brand-300);
        box-shadow: var(--elev-2), var(--elev-glow-brand);
        transform: scale(1.1);
    }
    .cmm-sidebar__collapse:focus-visible {
        outline: none;
        border-color: var(--brand-500);
        box-shadow: var(--elev-2), var(--elev-glow-brand);
    }
    /* Chevron rotation reflects intent: collapsed -> points-right ("open me"),
       pinned -> points-left ("close me"). In rail (collapsed) mode the pill is
       hidden by default so only icons show; it fades in when the cursor enters
       the sidebar. When pinned open, it's always visible. */
    .cmm-shell--collapsed .cmm-sidebar__collapse {
        transform: rotate(180deg);
        opacity: 0;
        pointer-events: none;
    }
    .cmm-shell--collapsed .cmm-sidebar:hover .cmm-sidebar__collapse,
    .cmm-shell--collapsed .cmm-sidebar:focus-within .cmm-sidebar__collapse,
    .cmm-shell--collapsed .cmm-sidebar__collapse:focus-visible {
        opacity: 1;
        pointer-events: auto;
    }
    .cmm-shell--collapsed .cmm-sidebar__collapse:hover {
        transform: rotate(180deg) scale(1.1);
    }
    /* Pinned-open pin indicator: a subtle brand-tinted ring on the pill. */
    .cmm-shell:not(.cmm-shell--collapsed) .cmm-sidebar__collapse[aria-pressed="true"] {
        color: var(--brand-600);
        border-color: var(--brand-300);
        background: var(--brand-50);
    }

    /* ---------- Rail-mode tooltips ----------
       Show the icon label as a floating tooltip when the rail is collapsed
       and not yet hover-expanded. shell-init.js mirrors each label into
       `data-cmm-tooltip` so the CSS can render it cheaply. */
    .cmm-nav-item[data-cmm-tooltip]::after {
        content: attr(data-cmm-tooltip);
        position: absolute;
        left: calc(100% + 14px);
        top: 50%;
        transform: translate(-6px, -50%);
        padding: 5px 10px;
        background: var(--text-primary, #0f172a);
        color: var(--surface-card, #fff);
        font-size: var(--fs-xs);
        font-weight: 500;
        white-space: nowrap;
        border-radius: 6px;
        box-shadow: var(--elev-2);
        pointer-events: none;
        opacity: 0;
        z-index: calc(var(--z-sidebar) + 1);
        transition: opacity var(--dur-fast) var(--ease-out),
                    transform var(--dur-fast) var(--ease-out);
    }
    @media (hover: hover) and (min-width: 1024px) {
        .cmm-shell--collapsed .cmm-sidebar:not(:hover):not(:focus-within) .cmm-nav-item:hover::after,
        .cmm-shell--collapsed .cmm-sidebar:not(:hover):not(:focus-within) .cmm-nav-item:focus-visible::after {
            opacity: 1;
            transform: translate(0, -50%);
        }
    }

    /* ---------- Hover-to-expand mini-rail ----------
       When collapsed, hovering (or focusing within) the sidebar temporarily
       expands it as an overlay over main content. Pin permanently via the
       collapse pill or Ctrl/Cmd+B. Intent-delay (~180ms) avoids accidental
       trips when the cursor merely passes by; close is immediate. */
    @media (hover: hover) and (min-width: 1024px) {
        .cmm-shell--collapsed .cmm-sidebar:hover,
        .cmm-shell--collapsed .cmm-sidebar:focus-within {
            width: var(--sidebar-w);
            box-shadow: var(--elev-3);
            transition-delay: 180ms, 180ms, 0s;
        }
        /* Stage 2: once the rail has widened, fade text content in. */
        .cmm-shell--collapsed .cmm-sidebar:hover .cmm-nav-item__label,
        .cmm-shell--collapsed .cmm-sidebar:focus-within .cmm-nav-item__label,
        .cmm-shell--collapsed .cmm-sidebar:hover .cmm-nav-item__badge,
        .cmm-shell--collapsed .cmm-sidebar:focus-within .cmm-nav-item__badge,
        .cmm-shell--collapsed .cmm-sidebar:hover .cmm-sidebar__section,
        .cmm-shell--collapsed .cmm-sidebar:focus-within .cmm-sidebar__section,
        .cmm-shell--collapsed .cmm-sidebar:hover .cmm-sidebar__brand-name,
        .cmm-shell--collapsed .cmm-sidebar:focus-within .cmm-sidebar__brand-name,
        .cmm-shell--collapsed .cmm-sidebar:hover .cmm-user-card__meta,
        .cmm-shell--collapsed .cmm-sidebar:focus-within .cmm-user-card__meta {
            opacity: 1;
            pointer-events: auto;
            transition-delay: 260ms;
        }
        /* While hover-expanded, restore the active-bar to full height. */
        .cmm-shell--collapsed .cmm-sidebar:hover .cmm-nav-item.is-active::before,
        .cmm-shell--collapsed .cmm-sidebar:focus-within .cmm-nav-item.is-active::before,
        .cmm-shell--collapsed .cmm-sidebar:hover .cmm-nav-item[aria-current="page"]::before,
        .cmm-shell--collapsed .cmm-sidebar:focus-within .cmm-nav-item[aria-current="page"]::before {
            transform: scaleY(1);
            transition-delay: 260ms;
        }
    }

    /* Reduced-motion users: skip animations, just switch states. */
    @media (prefers-reduced-motion: reduce) {
        .cmm-sidebar,
        .cmm-sidebar__brand-name,
        .cmm-sidebar__section,
        .cmm-nav-item__label,
        .cmm-nav-item__badge,
        .cmm-user-card__meta,
        .cmm-nav-item[data-cmm-tooltip]::after,
        .cmm-nav-item.is-active::before {
            transition-duration: 0ms !important;
            transition-delay: 0ms !important;
        }
    }

    /* ---------- Topbar ---------- */
    .cmm-topbar {
        grid-area: topbar;
        position: sticky;
        top: 0;
        z-index: var(--z-topbar);
        height: var(--topbar-h);
        display: flex;
        align-items: center;
        gap: 16px;
        padding: 0 var(--gutter);
        background: var(--surface-glass-strong);
        -webkit-backdrop-filter: saturate(140%) blur(12px);
        backdrop-filter: saturate(140%) blur(12px);
        border-bottom: 1px solid var(--border-color, #e5e7eb);
    }

    .cmm-breadcrumbs {
        display: flex;
        align-items: center;
        gap: 6px;
        font-size: var(--fs-sm);
        color: var(--text-muted, #6b7280);
        min-width: 0;
    }
    .cmm-breadcrumbs__crumb {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        color: inherit;
        text-decoration: none;
        transition: color var(--dur-fast) var(--ease-out);
    }
    .cmm-breadcrumbs__crumb:hover { color: var(--brand-600); }
    .cmm-breadcrumbs__crumb.is-current {
        color: var(--text-primary);
        font-weight: 600;
    }
    .cmm-breadcrumbs__sep { opacity: 0.5; }

    .cmm-topbar__search {
        flex: 1;
        max-width: 520px;
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 7px 12px;
        background: var(--surface-sunken);
        border: 1px solid transparent;
        border-radius: 10px;
        color: var(--text-secondary);
        font-size: var(--fs-sm);
        cursor: text;
        position: relative;
        transition:
            background var(--dur-fast) var(--ease-out),
            border-color var(--dur-fast) var(--ease-out),
            box-shadow var(--dur-fast) var(--ease-out);
    }
    .cmm-topbar__search:hover,
    .cmm-topbar__search:focus-within {
        background: var(--surface-card);
        border-color: var(--brand-300);
        box-shadow: var(--elev-glow-brand);
    }
    .cmm-topbar__search input {
        flex: 1;
        border: none;
        background: transparent;
        outline: none;
        font: inherit;
        color: inherit;
    }
    .cmm-topbar__search-placeholder {
        flex: 1;
        text-align: left;
        color: var(--text-muted);
        font: inherit;
    }
    button.cmm-topbar__search {
        font: inherit;
        text-align: left;
    }
    .cmm-topbar__search kbd {
        font-family: var(--font-mono);
        font-size: 10px;
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        padding: 1px 5px;
        border-radius: 4px;
        color: var(--text-muted);
    }

    /* ---- Inline topbar ticker/company search (no modal) ---- */
    .cmm-topbar__search-input {
        flex: 1;
        min-width: 0;
        border: none;
        background: transparent;
        outline: none;
        font: inherit;
        color: var(--text-primary);
    }
    .cmm-topbar__search-input::placeholder { color: var(--text-muted); }
    /* When the field is in use, drop the "/" hint so it doesn't crowd the box. */
    .cmm-topbar__search--inline:focus-within > kbd { display: none; }
    .cmm-topbar__search-results {
        position: absolute;
        top: calc(100% + 6px);
        left: 0;
        right: 0;
        z-index: 60;
        max-height: min(60vh, 380px);
        overflow-y: auto;
        padding: 6px;
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        border-radius: 12px;
        box-shadow: var(--elev-3, 0 12px 32px rgba(0, 0, 0, 0.18));
    }
    .cmm-topbar__search-results[hidden] { display: none; }

    .cmm-topbar__actions {
        display: flex;
        align-items: center;
        gap: 6px;
        margin-left: auto;
    }
    .cmm-icon-btn {
        position: relative;
        width: 36px;
        height: 36px;
        border-radius: 10px;
        border: none;
        background: transparent;
        color: var(--text-secondary);
        cursor: pointer;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        transition:
            background var(--dur-fast) var(--ease-out),
            color var(--dur-fast) var(--ease-out),
            transform var(--dur-fast) var(--ease-out);
    }
    .cmm-icon-btn:hover {
        background: var(--surface-sunken);
        color: var(--brand-600);
    }
    .cmm-icon-btn:active { transform: scale(0.94); }
    .cmm-icon-btn__dot {
        position: absolute;
        top: 7px;
        right: 7px;
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: var(--bear);
        box-shadow: 0 0 0 2px var(--surface-card);
    }

    /* ---------- Main content region ---------- */
    .cmm-main {
        grid-area: main;
        min-width: 0;
        padding: 24px var(--gutter) 80px;
    }
    .cmm-main__inner {
        max-width: var(--content-max);
        margin: 0 auto;
    }

    /* Page header (replaces giant purple gradient block) */
    .cmm-page-header {
        display: flex;
        align-items: flex-end;
        justify-content: space-between;
        gap: 16px;
        margin-bottom: 20px;
        flex-wrap: wrap;
    }
    .cmm-page-header__title {
        font-size: var(--fs-2xl);
        font-weight: 700;
        letter-spacing: var(--tracking-tight);
        color: var(--text-primary);
        margin: 0;
        line-height: var(--lh-tight);
    }
    .cmm-page-header__subtitle {
        margin: 4px 0 0;
        font-size: var(--fs-sm);
        color: var(--text-muted);
    }
    .cmm-page-header__actions {
        display: flex;
        gap: 8px;
        flex-shrink: 0;
    }

    /* ---------- Mobile: off-canvas sidebar, hamburger topbar ---------- */
    @media (max-width: 1023px) {
        /* Both selectors are listed on purpose: `.cmm-shell--collapsed`
           (specificity 0,2,0) sets a 2-track `<sidebar> 1fr` grid, which would
           otherwise out-specify a bare `.cmm-shell { grid-template-columns:1fr }`
           here and leave a 2-column grid under single-column areas — cramming
           `main` into the ~68px sidebar track. Matching the specificity (and
           winning on source order) forces a true single column when collapsed. */
        .cmm-shell,
        .cmm-shell.cmm-shell--collapsed {
            grid-template-columns: 1fr;
            grid-template-areas:
                "topbar"
                "main";
        }
        .cmm-sidebar {
            position: fixed;
            top: 0;
            left: 0;
            width: var(--sidebar-w);
            transform: translateX(-100%);
            transition: transform var(--dur-base) var(--ease-out-soft);
            box-shadow: var(--elev-4);
        }
        /* A persisted "collapsed" preference must not shrink the OFF-CANVAS drawer to a
           ~68px icon-only rail with hidden labels — below 1024 the sidebar is a full
           slide-in drawer, so render it expanded regardless of the collapse flag. Mirrors
           the desktop hover-expand un-hide; wins over the collapse rules on source order. */
        .cmm-shell--collapsed .cmm-sidebar { width: var(--sidebar-w); }
        .cmm-shell--collapsed .cmm-nav-item__label,
        .cmm-shell--collapsed .cmm-nav-item__badge,
        .cmm-shell--collapsed .cmm-sidebar__section,
        .cmm-shell--collapsed .cmm-sidebar__brand-name,
        .cmm-shell--collapsed .cmm-user-card__meta {
            opacity: 1;
            pointer-events: auto;
        }
        .cmm-shell--collapsed .cmm-nav-item.is-active::before,
        .cmm-shell--collapsed .cmm-nav-item[aria-current="page"]::before {
            transform: scaleY(1);
        }
        .cmm-shell.cmm-shell--drawer-open .cmm-sidebar {
            transform: translateX(0);
        }
        .cmm-shell.cmm-shell--drawer-open::after {
            content: "";
            position: fixed;
            inset: 0;
            background: rgba(15, 23, 42, 0.5);
            -webkit-backdrop-filter: blur(2px);
            backdrop-filter: blur(2px);
            z-index: calc(var(--z-sidebar) - 1);
            animation: cmm-fade-in var(--dur-base) var(--ease-out);
        }
        .cmm-sidebar__collapse { display: none; }
        .cmm-topbar__menu { display: inline-flex; }
    }
    .cmm-topbar__menu { display: none; }

    @keyframes cmm-fade-in {
        from { opacity: 0; }
        to   { opacity: 1; }
    }
}

/* =============================================================
   View Transitions API - applies only when supported.
   Page swaps cross-fade smoothly; sidebar/topbar stay rock-solid
   via view-transition-name (continuous identity).
   ============================================================= */
@layer components {
    @supports (view-transition-name: none) {
        .cmm-sidebar { view-transition-name: cmm-sidebar; }
        .cmm-topbar  { view-transition-name: cmm-topbar; }
        .cmm-main    { view-transition-name: cmm-main; }
    }
}

::view-transition-old(cmm-main),
::view-transition-new(cmm-main) {
    animation-duration: var(--dur-page);
    animation-timing-function: var(--ease-out-soft);
}
::view-transition-old(cmm-main) {
    animation-name: cmm-main-out;
}
::view-transition-new(cmm-main) {
    animation-name: cmm-main-in;
}
@keyframes cmm-main-out {
    to { opacity: 0; transform: translateY(-4px); }
}
@keyframes cmm-main-in {
    from { opacity: 0; transform: translateY(6px); }
}

/* =============================================================
   Search Overlay (V2 styling, V1 behavior)
   ============================================================= */
@layer components {
    /* The full-screen search overlay was replaced by the inline topbar combobox
       (.cmm-topbar__search--inline). The shared result-row + state styles below
       (.cmm-search-row, __loading/__empty/__error) are reused by the inline
       dropdown and the ticker typeahead. */
    .cmm-search-row {
        display: flex; align-items: center; gap: 12px;
        width: 100%;
        padding: 10px 12px;
        border-radius: 8px;
        background: transparent;
        border: 1px solid transparent;
        cursor: pointer;
        text-align: left;
        color: var(--text-primary);
        transition: background var(--dur-fast) var(--ease-out), border-color var(--dur-fast) var(--ease-out);
    }
    .cmm-search-row:hover,
    .cmm-search-row[aria-selected="true"] {
        background: var(--brand-50);
        border-color: var(--brand-200);
    }
    .cmm-search-row__sym {
        flex-shrink: 0;
        min-width: 56px;
        text-align: center;
        font-weight: 700;
        font-size: var(--fs-xs);
        color: var(--brand-700);
        background: var(--brand-50);
        padding: 4px 8px;
        border-radius: 6px;
    }
    .cmm-search-row__name {
        flex: 1;
        font-size: var(--fs-sm);
        color: var(--text-secondary);
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .cmm-search-row__badge {
        font-size: 10px;
        font-weight: 600;
        color: var(--bull-strong, #047857);
        background: var(--bull-soft, #d1fae5);
        padding: 2px 7px;
        border-radius: 999px;
        display: inline-flex;
        align-items: center;
        gap: 4px;
    }
    .cmm-search-row__chev { color: var(--text-muted); font-size: 11px; }
    .cmm-search-overlay__loading,
    .cmm-search-overlay__empty,
    .cmm-search-overlay__error {
        text-align: center;
        padding: 32px 16px;
        color: var(--text-muted);
        font-size: var(--fs-sm);
    }
    .cmm-search-overlay__error { color: var(--bear); }

    @keyframes cmm-fade-in { from { opacity: 0; } to { opacity: 1; } }
    @keyframes cmm-pop-in { from { opacity: 0; transform: translateY(-8px) scale(0.98); } to { opacity: 1; transform: none; } }
}

/* ---------------------------------------------------------------------------
   "How it works" educational modal - shell-wide, self-contained styling so it
   renders on every page (not just those that load pages-v2.css). Opened via
   data-cmm-action="open-learn"; fade handled by the .is-open class toggle.
   --------------------------------------------------------------------------- */
@layer components {
    .cmm-learn-modal {
        position: fixed;
        inset: 0;
        z-index: 1200;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 24px;
        opacity: 0;
        transition: opacity 0.2s var(--ease-out, ease);
    }
    .cmm-learn-modal[hidden] { display: none; }
    .cmm-learn-modal.is-open { opacity: 1; }

    .cmm-learn-modal__backdrop {
        position: absolute;
        inset: 0;
        background: rgba(10, 12, 20, 0.55);
        backdrop-filter: blur(4px);
        -webkit-backdrop-filter: blur(4px);
    }
    .cmm-learn-modal__panel {
        position: relative;
        width: min(640px, 100%);
        max-height: 85vh;
        overflow-y: auto;
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        border-radius: 16px;
        box-shadow: var(--elev-3, 0 24px 64px rgba(0, 0, 0, 0.35));
        transform: translateY(10px) scale(0.985);
        transition: transform 0.2s var(--ease-out, ease);
    }
    .cmm-learn-modal.is-open .cmm-learn-modal__panel { transform: none; }

    .cmm-learn-modal__head {
        position: sticky;
        top: 0;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 18px 20px;
        background: var(--surface-card);
        border-bottom: 1px solid var(--border-color);
        border-radius: 16px 16px 0 0;
    }
    .cmm-learn-modal__title {
        margin: 0;
        font-size: var(--fs-lg, 1.125rem);
        font-weight: 700;
        color: var(--text-primary);
        display: inline-flex;
        align-items: center;
        gap: 10px;
    }
    .cmm-learn-modal__title i { color: var(--brand-700); }

    .cmm-learn-modal__body { padding: 20px; color: var(--text-secondary); line-height: 1.6; }
    .cmm-learn-modal__body h3 {
        margin: 22px 0 8px;
        font-size: var(--fs-md, 1rem);
        font-weight: 700;
        color: var(--text-primary);
    }
    .cmm-learn-modal__body p { margin: 0 0 12px; }
    .cmm-learn-modal__body ul { margin: 0 0 12px; padding-left: 20px; }
    .cmm-learn-modal__body li { margin: 0 0 6px; }
    .cmm-learn-modal__more { margin-top: 18px; font-weight: 600; }
    .cmm-learn-modal__more a { color: var(--brand-700); }

    .cmm-learn-callout {
        display: flex;
        gap: 12px;
        padding: 12px 14px;
        border-radius: 10px;
        margin: 0 0 16px;
        font-size: var(--fs-sm, 0.9rem);
    }
    .cmm-learn-callout i { margin-top: 2px; }
    .cmm-learn-callout p { margin: 0; }
    .cmm-learn-callout--warn {
        background: color-mix(in srgb, #f59e0b 12%, transparent);
        border: 1px solid color-mix(in srgb, #f59e0b 35%, transparent);
    }
    .cmm-learn-callout--warn i { color: #d97706; }
    .cmm-learn-callout--danger {
        background: color-mix(in srgb, #ef4444 12%, transparent);
        border: 1px solid color-mix(in srgb, #ef4444 35%, transparent);
    }
    .cmm-learn-callout--danger i { color: #dc2626; }

    .cmm-topbar__learn { margin-left: 4px; }

    /* Litigation-protection badge in the topbar - subtle outlined pill that
       opens the educational disclosure. Kept understated by design. */
    .cmm-topbar__disclaimer {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        margin-left: 6px;
        padding: 5px 10px;
        border: 1px solid var(--border-color);
        border-radius: 999px;
        background: transparent;
        color: var(--text-muted);
        font-size: 11px;
        font-weight: 600;
        line-height: 1;
        white-space: nowrap;
        cursor: pointer;
        transition: color var(--dur-fast, .15s) ease, border-color var(--dur-fast, .15s) ease, background var(--dur-fast, .15s) ease;
    }
    .cmm-topbar__disclaimer i { font-size: 12px; opacity: 0.8; }
    .cmm-topbar__disclaimer:hover {
        color: var(--text-primary);
        border-color: var(--brand-300, #a5b4fc);
        background: var(--surface-sunken, rgba(0, 0, 0, .04));
    }
    @media (max-width: 720px) {
        .cmm-topbar__disclaimer-text { display: none; }
        .cmm-topbar__disclaimer { padding: 6px; gap: 0; }
    }

    body.cmm-modal-open { overflow: hidden; }

    /* -----------------------------------------------------------------------
       Alerts modal - opened by the topbar bell (cmm-alerts-modal in topbar.html,
       driven by core/shell/alerts-modal.js). Replaces the old /alerts.html page:
       email on/off, frequency, and a deep-linked watchlist. Self-contained so it
       renders on every shell page (overlay layer = 1200, same as the learn modal;
       only one is ever open at a time).
       --------------------------------------------------------------------- */
    /* Compound selector: the base .cmm-topbar__badge rule is declared LATER
       in this file with equal specificity, so a bare --dot selector loses the
       cascade and the dot renders as an empty 16px count pill. */
    .cmm-topbar__badge.cmm-topbar__badge--dot {
        min-width: 9px;
        width: 9px;
        height: 9px;
        padding: 0;
        top: 0;
        right: 0;
    }

    .cmm-alertmodal {
        position: fixed;
        inset: 0;
        z-index: 1200;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 24px;
        opacity: 0;
        transition: opacity 0.2s var(--ease-out, ease);
    }
    .cmm-alertmodal[hidden] { display: none; }
    .cmm-alertmodal.is-open { opacity: 1; }

    .cmm-alertmodal__backdrop {
        position: absolute;
        inset: 0;
        background: rgba(10, 12, 20, 0.55);
        backdrop-filter: blur(4px);
        -webkit-backdrop-filter: blur(4px);
    }
    .cmm-alertmodal__panel {
        position: relative;
        display: flex;
        flex-direction: column;
        width: min(520px, 100%);
        max-height: 85vh;
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        border-radius: 16px;
        box-shadow: var(--elev-3, 0 24px 64px rgba(0, 0, 0, 0.35));
        transform: translateY(10px) scale(0.985);
        transition: transform 0.2s var(--ease-out, ease);
        overflow: hidden;
    }
    .cmm-alertmodal.is-open .cmm-alertmodal__panel { transform: none; }

    .cmm-alertmodal__head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 16px 20px;
        border-bottom: 1px solid var(--border-color);
        flex: 0 0 auto;
    }
    .cmm-alertmodal__title {
        margin: 0;
        font-size: var(--fs-lg, 1.125rem);
        font-weight: 700;
        color: var(--text-primary);
        display: inline-flex;
        align-items: center;
        gap: 10px;
    }
    .cmm-alertmodal__title i { color: var(--brand-700); }

    .cmm-alertmodal__body {
        padding: 18px 20px 20px;
        overflow-y: auto;
    }

    /* Watchlist */
    .cmm-alertmodal__listhead {
        display: flex;
        align-items: center;
        justify-content: space-between;
        margin: 20px 0 10px;
    }
    .cmm-alertmodal__listtitle {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        font-weight: 700;
        color: var(--text-primary);
        font-size: 0.95rem;
    }
    .cmm-alertmodal__listtitle i { color: var(--brand-700); }
    .cmm-alertmodal__count { font-weight: 600; color: var(--text-muted, var(--text-secondary)); font-size: 0.8rem; }

    .cmm-alertmodal__add { display: flex; gap: 8px; margin-bottom: 8px; }
    .cmm-alertmodal__add-input {
        flex: 1;
        min-width: 0;
        padding: 9px 12px;
        border: 1px solid var(--border-color);
        border-radius: 10px;
        background: var(--surface-app, transparent);
        color: var(--text-primary);
        font-size: 0.9rem;
        text-transform: uppercase;
    }
    .cmm-alertmodal__add-input::placeholder { text-transform: none; color: var(--text-muted, #94a3b8); }
    .cmm-alertmodal__add-input:focus { outline: none; border-color: var(--brand-700); }
    .cmm-alertmodal__add-btn {
        flex: 0 0 auto;
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 9px 14px;
        border: none;
        border-radius: 10px;
        background: var(--brand-700);
        color: #fff;
        font-weight: 600;
        font-size: 0.86rem;
        cursor: pointer;
    }
    .cmm-alertmodal__add-btn:hover { filter: brightness(1.05); }
    .cmm-alertmodal__add-error { color: var(--danger, #dc2626); font-size: 0.8rem; margin: 0 0 8px; }
    .cmm-alertmodal__add-error[hidden] { display: none; }

    /* ---- Shared ticker typeahead dropdown (alerts add box, etc.) ----
       Reuses the .cmm-search-row rows from the topbar search. */
    .cmm-alertmodal__add { position: relative; }
    .cmm-typeahead-results {
        position: absolute;
        top: calc(100% + 6px);
        left: 0;
        right: 0;
        z-index: 30;
        max-height: 260px;
        overflow-y: auto;
        padding: 6px;
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        border-radius: 12px;
        box-shadow: var(--elev-3, 0 12px 32px rgba(0, 0, 0, 0.18));
    }
    .cmm-typeahead-results[hidden] { display: none; }

    .cmm-alertmodal__upsell {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 12px 14px;
        margin-bottom: 10px;
        border: 1px solid var(--brand-300, #a5b4fc);
        border-radius: 12px;
        background: var(--surface-sunken, rgba(124, 58, 237, 0.06));
    }
    .cmm-alertmodal__upsell[hidden] { display: none; }
    .cmm-alertmodal__upsell-text {
        display: flex;
        align-items: center;
        gap: 10px;
        font-size: 0.82rem;
        line-height: 1.4;
        color: var(--text-secondary);
    }
    .cmm-alertmodal__upsell-text i { color: var(--brand-700); }
    .cmm-alertmodal__upsell-text strong { color: var(--text-primary); }
    .cmm-alertmodal__upsell-btn {
        flex: 0 0 auto;
        white-space: nowrap;
        padding: 8px 14px;
        border: none;
        border-radius: 10px;
        background: var(--brand-700);
        color: #fff;
        font-weight: 600;
        font-size: 0.82rem;
        cursor: pointer;
    }
    .cmm-alertmodal__upsell-btn:hover { filter: brightness(1.05); }

    .cmm-alertmodal__table {
        max-height: 44vh;
        overflow-y: auto;
        border: 1px solid var(--border-color);
        border-radius: 12px;
    }
    .cmm-alertmodal__row {
        display: grid;
        grid-template-columns: auto 1fr auto auto;
        align-items: center;
        gap: 12px;
        padding: 11px 14px;
        border-bottom: 1px solid var(--border-color);
    }
    .cmm-alertmodal__row:last-child { border-bottom: none; }
    .cmm-alertmodal__row:hover { background: var(--surface-sunken, rgba(0, 0, 0, 0.03)); }
    .cmm-alertmodal__row--head {
        position: sticky;
        top: 0;
        z-index: 1;
        background: var(--surface-card);
        padding-top: 9px;
        padding-bottom: 9px;
    }
    .cmm-alertmodal__row--head:hover { background: var(--surface-card); }
    .cmm-alertmodal__hcell {
        font-size: 0.68rem;
        font-weight: 700;
        letter-spacing: 0.05em;
        text-transform: uppercase;
        color: var(--text-muted, var(--text-secondary));
    }
    .cmm-alertmodal__sym {
        font-weight: 700;
        font-size: 0.9rem;
        color: var(--brand-700);
        text-decoration: none;
        font-family: var(--font-mono, 'JetBrains Mono', monospace);
    }
    .cmm-alertmodal__sym:hover { text-decoration: underline; }
    .cmm-alertmodal__sym.is-flat { color: var(--text-primary); }
    .cmm-alertmodal__name {
        color: var(--text-secondary);
        font-size: 0.85rem;
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
    }
    .cmm-alertmodal__when {
        color: var(--text-muted, var(--text-secondary));
        font-size: 0.8rem;
        text-decoration: none;
        white-space: nowrap;
    }
    .cmm-alertmodal__when:hover { color: var(--brand-700); text-decoration: underline; }
    .cmm-alertmodal__when.is-empty { color: var(--text-muted, #94a3b8); font-style: italic; }
    .cmm-alertmodal__remove {
        opacity: 0;
        flex: 0 0 auto;
        width: 26px;
        height: 26px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: none;
        border-radius: 8px;
        background: transparent;
        color: var(--text-muted, #94a3b8);
        cursor: pointer;
        transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
    }
    .cmm-alertmodal__row:hover .cmm-alertmodal__remove,
    .cmm-alertmodal__row:focus-within .cmm-alertmodal__remove { opacity: 1; }
    .cmm-alertmodal__remove:hover { background: rgba(220, 38, 38, 0.12); color: var(--danger, #dc2626); }
    @media (hover: none) { .cmm-alertmodal__remove { opacity: 0.6; } }

    .cmm-alertmodal__empty {
        text-align: center;
        padding: 28px 16px;
        color: var(--text-muted, var(--text-secondary));
    }
    .cmm-alertmodal__empty i { font-size: 22px; opacity: 0.6; display: block; margin-bottom: 8px; }
    .cmm-alertmodal__empty p { margin: 0; }
    .cmm-alertmodal__empty-hint { font-size: 0.8rem; opacity: 0.8; margin-top: 4px !important; }

    /* Community replies/mentions section (populated from /api/notifications) */
    .cmm-alertmodal__notifs {
        display: flex;
        flex-direction: column;
        gap: 2px;
        margin-top: 4px;
    }
    .cmm-alertmodal__notif {
        display: flex;
        align-items: flex-start;
        gap: 10px;
        padding: 8px 10px;
        border-radius: 10px;
        text-decoration: none;
        color: inherit;
        transition: background 0.12s ease;
    }
    .cmm-alertmodal__notif:hover { background: var(--surface-sunken, rgba(0, 0, 0, 0.04)); }
    .cmm-alertmodal__notif.is-unread {
        background: var(--brand-50, rgba(99, 102, 241, 0.07));
    }
    .cmm-alertmodal__notif-body { flex: 1 1 auto; min-width: 0; }
    .cmm-alertmodal__notif-line {
        display: block;
        font-size: 0.85rem;
        color: var(--text-primary);
    }
    .cmm-alertmodal__notif-preview {
        display: block;
        font-size: 0.8rem;
        color: var(--text-muted, var(--text-secondary));
        overflow: hidden;
        text-overflow: ellipsis;
        white-space: nowrap;
        margin-top: 1px;
    }
    .cmm-alertmodal__notif-when {
        flex: 0 0 auto;
        font-size: 0.75rem;
        color: var(--text-muted, var(--text-secondary));
        white-space: nowrap;
        padding-top: 2px;
    }
    /* Beta trade-event rows: a small robot badge distinguishes them from the
       community reply/mention rows they sit alongside. */
    .cmm-alertmodal__notif-icon--trade {
        flex: 0 0 auto;
        width: 26px;
        height: 26px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 8px;
        font-size: 12px;
        color: var(--brand-600, #6d28d9);
        background: var(--brand-50, rgba(124, 58, 237, 0.12));
        margin-top: 1px;
    }
    html.theme-dark .cmm-alertmodal__notif-icon--trade {
        color: #c4b5fd;
        background: rgba(124, 58, 237, 0.18);
    }
    /* Admin-only new-user-registered rows: green user badge (only admins ever
       receive this type, so no plan/role check is needed client-side). */
    .cmm-alertmodal__notif-icon--signup {
        flex: 0 0 auto;
        width: 26px;
        height: 26px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 8px;
        font-size: 12px;
        margin-top: 1px;
        color: var(--success-600, #059669);
        background: var(--success-50, rgba(16, 185, 129, 0.12));
    }
    html.theme-dark .cmm-alertmodal__notif-icon--signup {
        color: #6ee7b7;
        background: rgba(16, 185, 129, 0.18);
    }

    .cmm-alertmodal__row.is-skeleton { pointer-events: none; }
    .cmm-alertmodal__sk {
        display: inline-block;
        height: 12px;
        border-radius: 6px;
        background: linear-gradient(90deg, var(--border-color) 25%, var(--surface-sunken, rgba(0, 0, 0, 0.06)) 37%, var(--border-color) 63%);
        background-size: 400% 100%;
        animation: cmm-alertmodal-sk 1.2s ease-in-out infinite;
    }
    @keyframes cmm-alertmodal-sk {
        0% { background-position: 100% 50%; }
        100% { background-position: 0 50%; }
    }

    @media (prefers-reduced-motion: reduce) {
        .cmm-alertmodal, .cmm-alertmodal__panel { transition: none; }
        .cmm-alertmodal__sk { animation: none; }
    }

    /* -----------------------------------------------------------------------
       Mandatory educational disclosure - full-screen, non-dismissible gate
       shown to authenticated users who have not yet accepted (web mirror of the
       mobile EducationalDisclaimerScreen). Injected + driven by
       core/shell/shell-init.js. Self-contained styling so it renders on every
       shell page. Sits above every other shell layer (learn modal = 1200).
       ----------------------------------------------------------------------- */
    .cmm-disclosure {
        position: fixed;
        inset: 0;
        z-index: 2000;
        display: flex;
        align-items: center;
        justify-content: center;
        padding: 20px;
        opacity: 0;
        transition: opacity 0.2s var(--ease-out, ease);
    }
    .cmm-disclosure[hidden] { display: none; }
    .cmm-disclosure.is-open { opacity: 1; }

    .cmm-disclosure__backdrop {
        position: absolute;
        inset: 0;
        background: rgba(8, 10, 18, 0.72);
        backdrop-filter: blur(5px);
        -webkit-backdrop-filter: blur(5px);
    }
    .cmm-disclosure__panel {
        position: relative;
        display: flex;
        flex-direction: column;
        width: min(620px, 100%);
        max-height: min(88vh, 760px);
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        border-radius: 18px;
        box-shadow: var(--elev-3, 0 24px 64px rgba(0, 0, 0, 0.45));
        overflow: hidden;
        transform: translateY(12px) scale(0.985);
        transition: transform 0.2s var(--ease-out, ease);
    }
    .cmm-disclosure.is-open .cmm-disclosure__panel { transform: none; }
    .cmm-disclosure__panel--shake { animation: cmm-disclosure-shake 0.4s ease; }
    @keyframes cmm-disclosure-shake {
        0%, 100% { transform: translateX(0); }
        20%, 60% { transform: translateX(-8px); }
        40%, 80% { transform: translateX(8px); }
    }

    .cmm-disclosure__head {
        display: flex;
        align-items: center;
        gap: 14px;
        padding: 20px 22px;
        border-bottom: 1px solid var(--border-color);
    }
    .cmm-disclosure__icon {
        flex: none;
        width: 42px;
        height: 42px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border-radius: 12px;
        color: var(--brand-700);
        background: color-mix(in srgb, var(--brand-700) 14%, transparent);
        font-size: 20px;
    }
    .cmm-disclosure__title {
        margin: 0;
        font-size: var(--fs-lg, 1.125rem);
        font-weight: 800;
        color: var(--text-primary);
    }
    .cmm-disclosure__subtitle {
        margin: 2px 0 0;
        font-size: var(--fs-xs, 0.74rem);
        font-weight: 600;
        letter-spacing: 0.03em;
        text-transform: uppercase;
        color: var(--text-muted);
    }
    /* Close button - only present in the dismissible (read-only) viewer. */
    .cmm-disclosure__close {
        flex: none;
        margin-left: auto;
        width: 34px;
        height: 34px;
        display: none;
        align-items: center;
        justify-content: center;
        border: none;
        border-radius: 9px;
        background: transparent;
        color: var(--text-muted);
        font-size: 17px;
        cursor: pointer;
        transition: color var(--dur-fast, .15s) ease, background var(--dur-fast, .15s) ease;
    }
    .cmm-disclosure__close:hover { color: var(--text-primary); background: var(--surface-sunken, rgba(0,0,0,.05)); }
    .cmm-disclosure--dismissible .cmm-disclosure__close { display: inline-flex; }
    .cmm-disclosure--dismissible .cmm-disclosure__footer,
    .cmm-disclosure--dismissible .cmm-disclosure__scrollhint { display: none; }

    .cmm-disclosure__body {
        overflow-y: auto;
        padding: 18px 22px;
        color: var(--text-secondary);
        line-height: 1.55;
        -webkit-overflow-scrolling: touch;
    }
    .cmm-disclosure__body:focus { outline: none; }
    .cmm-disclosure__section {
        border-left: 3px solid var(--border-color);
        padding: 2px 0 2px 14px;
        margin: 0 0 18px;
    }
    .cmm-disclosure__section:last-child { margin-bottom: 0; }
    .cmm-disclosure__shead {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        margin: 0 0 8px;
        font-size: var(--fs-sm, 0.92rem);
        font-weight: 800;
        letter-spacing: 0.01em;
    }
    .cmm-disclosure__section p { margin: 0 0 8px; font-size: var(--fs-sm, 0.92rem); }
    .cmm-disclosure__section p:last-child { margin-bottom: 0; }
    .cmm-disclosure__section ul { margin: 0; padding-left: 18px; }
    .cmm-disclosure__section li { margin: 0 0 6px; font-size: var(--fs-sm, 0.9rem); }
    .cmm-disclosure__section a { color: var(--brand-700); font-weight: 600; }
    .cmm-disclosure__strong { font-weight: 800; color: var(--text-primary); }
    .cmm-disclosure__flag { font-weight: 800; }

    .cmm-disclosure__scrollhint {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 8px;
        padding: 9px 12px;
        font-size: var(--fs-xs, 0.8rem);
        color: var(--text-muted);
        border-top: 1px solid var(--border-color);
        background: var(--surface-card);
    }
    .cmm-disclosure__scrollhint[hidden] { display: none; }

    .cmm-disclosure__footer {
        padding: 14px 22px 18px;
        border-top: 1px solid var(--border-color);
        background: var(--surface-card);
    }
    .cmm-disclosure__optin {
        display: flex;
        align-items: flex-start;
        gap: 10px;
        margin: 0 0 12px;
        font-size: var(--fs-sm, 0.9rem);
        color: var(--text-secondary);
        cursor: pointer;
    }
    .cmm-disclosure__optin input {
        margin-top: 2px;
        width: 16px;
        height: 16px;
        flex: none;
        accent-color: var(--brand-700);
    }
    .cmm-disclosure__error {
        margin: 0 0 10px;
        font-size: var(--fs-sm, 0.88rem);
        font-weight: 600;
        color: #dc2626;
    }
    .cmm-disclosure__error[hidden] { display: none; }
    .cmm-disclosure__accept {
        width: 100%;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        gap: 10px;
        padding: 13px 18px;
        border: none;
        border-radius: 12px;
        font-size: var(--fs-md, 1rem);
        font-weight: 700;
        color: #fff;
        background: var(--brand-700, #7c3aed);
        cursor: pointer;
        transition: background 0.15s ease, opacity 0.15s ease;
    }
    .cmm-disclosure__accept:hover:not(:disabled) { background: var(--brand-800, #6d28d9); }
    .cmm-disclosure__accept:disabled {
        background: var(--border-color);
        color: var(--text-muted);
        cursor: not-allowed;
    }
    .cmm-disclosure__accept.is-busy { opacity: 0.85; cursor: progress; }
    .cmm-disclosure__note {
        margin: 12px 0 0;
        font-size: var(--fs-xs, 0.78rem);
        color: var(--text-muted);
        text-align: center;
    }

    /* ---------- Topbar actions: saved popover + count badge ---------- */
    .cmm-topbar__actions { position: relative; }
    .cmm-topbar__saved { position: relative; }
    .cmm-topbar__badge {
        position: absolute;
        top: -2px;
        right: -2px;
        min-width: 16px;
        height: 16px;
        padding: 0 4px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 10px;
        font-weight: 700;
        line-height: 1;
        color: #fff;
        background: var(--brand-700, #7c3aed);
        border: 2px solid var(--surface-app, var(--bg-primary, #fff));
        border-radius: 999px;
        pointer-events: none;
    }
    .cmm-topbar__badge[hidden] { display: none; }

    .cmm-saved-popover {
        position: absolute;
        top: calc(100% + 10px);
        right: 0;
        width: min(360px, calc(100vw - 32px));
        max-height: min(70vh, 520px);
        display: flex;
        flex-direction: column;
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        border-radius: 14px;
        box-shadow: var(--elev-3, 0 24px 64px rgba(0, 0, 0, 0.35));
        z-index: calc(var(--z-topbar, 100) + 5);
        opacity: 0;
        transform: translateY(-6px);
        transition: opacity 0.16s var(--ease-out, ease), transform 0.16s var(--ease-out, ease);
    }
    .cmm-saved-popover[hidden] { display: none; }
    .cmm-saved-popover.is-open { opacity: 1; transform: none; }

    .cmm-saved-popover__head {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
        padding: 12px 14px;
        border-bottom: 1px solid var(--border-color);
    }
    .cmm-saved-popover__title {
        display: inline-flex;
        align-items: center;
        gap: 8px;
        font-weight: 700;
        color: var(--text-primary);
        font-size: var(--fs-sm, 0.9rem);
    }
    .cmm-saved-popover__title i { color: var(--brand-700); }
    .cmm-saved-popover__count { color: var(--text-muted); font-weight: 500; }
    .cmm-saved-popover__all {
        font-size: var(--fs-xs, 0.8rem);
        font-weight: 600;
        color: var(--brand-700);
        display: inline-flex;
        align-items: center;
        gap: 5px;
        white-space: nowrap;
    }

    .cmm-saved-popover__list {
        overflow-y: auto;
        padding: 6px;
        display: flex;
        flex-direction: column;
        gap: 4px;
    }

    .cmm-saved-item {
        display: flex;
        align-items: center;
        gap: 10px;
        padding: 9px 10px;
        border-radius: 10px;
        border-left: 3px solid var(--border-color);
        background: var(--surface-app, transparent);
        transition: background 0.12s ease;
    }
    .cmm-saved-item:hover { background: color-mix(in srgb, var(--brand-700) 7%, transparent); }
    .cmm-saved-item[data-dir="bullish"] { border-left-color: #16a34a; }
    .cmm-saved-item[data-dir="bearish"] { border-left-color: #dc2626; }
    .cmm-saved-item__main { flex: 1; min-width: 0; }
    .cmm-saved-item__top { display: flex; align-items: center; gap: 8px; }
    .cmm-saved-item__sym { font-weight: 700; color: var(--text-primary); font-size: var(--fs-sm, 0.9rem); }
    .cmm-saved-item__dir {
        font-size: var(--fs-xs, 0.78rem);
        color: var(--text-muted);
        display: inline-flex;
        align-items: center;
        gap: 4px;
    }
    .cmm-saved-item[data-dir="bullish"] .cmm-saved-item__dir { color: #16a34a; }
    .cmm-saved-item[data-dir="bearish"] .cmm-saved-item__dir { color: #dc2626; }
    .cmm-saved-item__headline {
        margin-top: 2px;
        font-size: var(--fs-xs, 0.8rem);
        color: var(--text-secondary);
        overflow: hidden;
        text-overflow: ellipsis;
        display: -webkit-box;
        -webkit-line-clamp: 2;
        -webkit-box-orient: vertical;
    }
    .cmm-saved-item__remove {
        flex: none;
        width: 28px;
        height: 28px;
        border: none;
        background: transparent;
        color: var(--text-muted);
        border-radius: 8px;
        cursor: pointer;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        transition: background 0.12s ease, color 0.12s ease;
    }
    .cmm-saved-item__remove:hover { background: color-mix(in srgb, #ef4444 14%, transparent); color: #dc2626; }

    .cmm-saved-popover__empty {
        padding: 28px 18px;
        text-align: center;
        color: var(--text-muted);
    }
    .cmm-saved-popover__empty i { font-size: 22px; display: block; margin-bottom: 10px; opacity: 0.7; }
    .cmm-saved-popover__empty p { margin: 0 0 4px; font-size: var(--fs-sm, 0.9rem); }
    .cmm-saved-popover__hint { font-size: var(--fs-xs, 0.8rem); }

    @media (prefers-reduced-motion: reduce) {
        .cmm-learn-modal, .cmm-learn-modal__panel { transition: none; }
        .cmm-saved-popover { transition: none; }
        .cmm-disclosure, .cmm-disclosure__panel { transition: none; }
        .cmm-disclosure__panel--shake { animation: none; }
    }
}

/* =============================================================
   Topbar plan CTAs.
   .cmm-upgrade-pill  - subtle nudge shown to signed-in FREE users only.
   .cmm-topbar-signin - guest CTA that opens the in-page auth modal.
   Both ship `hidden`; shell-init.js reveals at most one per auth state.
   ============================================================= */
@layer components {
    .cmm-upgrade-pill {
        position: relative;
        display: inline-flex;
        align-items: center;
        gap: 7px;
        height: 34px;
        padding: 0 14px;
        border-radius: 999px;
        border: 1px solid color-mix(in srgb, #f59e0b 50%, transparent);
        background: linear-gradient(135deg, #2563eb, #8b5cf6);
        color: #fff;
        font: inherit;
        font-size: var(--fs-xs, 12px);
        font-weight: 800;
        white-space: nowrap;
        cursor: pointer;
        box-shadow: 0 10px 24px rgba(37, 99, 235, 0.24);
        transition:
            filter var(--dur-fast) var(--ease-out),
            transform var(--dur-fast) var(--ease-out),
            box-shadow var(--dur-fast) var(--ease-out);
    }
    .cmm-upgrade-pill:hover {
        filter: brightness(1.07);
        transform: translateY(-1px);
        box-shadow: 0 14px 30px rgba(37, 99, 235, 0.32);
    }
    .cmm-upgrade-pill i { font-size: 12px; color: #fde68a; }

    /* "N prominent signals locked" count bubble on the upgrade pill (free users,
       News page). Small gold notification dot; hover/focus reveals the popover. */
    .cmm-upgrade-pill__count {
        position: absolute;
        top: -6px;
        right: -6px;
        min-width: 17px;
        height: 17px;
        padding: 0 4px;
        border-radius: 999px;
        background: #f59e0b;
        color: #3a2606;
        font-size: 10px;
        font-weight: 800;
        line-height: 17px;
        text-align: center;
        pointer-events: none;
    }
    .cmm-upgrade-pill__pop {
        position: absolute;
        top: calc(100% + 8px);
        right: 0;
        display: none;
        z-index: var(--z-dropdown, 1000);
        width: max-content;
        max-width: 230px;
        padding: 8px 10px;
        border-radius: 8px;
        border: 1px solid rgba(255, 255, 255, 0.08);
        background: #1f2937;
        color: #f9fafb;
        font-size: 12px;
        font-weight: 600;
        line-height: 1.35;
        white-space: normal;
        box-shadow: 0 12px 28px rgba(15, 23, 42, 0.28);
    }
    .cmm-upgrade-pill.has-lock:hover .cmm-upgrade-pill__pop,
    .cmm-upgrade-pill.has-lock:focus-within .cmm-upgrade-pill__pop {
        display: block;
    }

    /* Quiet PRO wordmark: prominence for every viewer, or server-owned access.
       Release timing is explained on detail, never used as card decoration. */
    .cmm-pro-mark,
    .cmm-lock-pill {
        display: inline-flex;
        align-items: center;
        padding: 2px 5px;
        border-radius: 5px;
        border: 1px solid var(--border-color);
        background: transparent;
        color: #92400e;
        font-size: 11px;
        font-weight: 600;
        letter-spacing: 0.04em;
        line-height: 1.4;
        white-space: nowrap;
        vertical-align: middle;
    }
    html.theme-dark .cmm-pro-mark,
    html.theme-dark .cmm-lock-pill { color: #d6b47a; }

    /* Inline "New" freshness badge (replaces the old "Breaking Now" rail).
       Injected by shell-init.js next to any relative time-since. Small + subtle. */
    .cmm-badge-new {
        display: inline-flex;
        align-items: center;
        margin-left: 6px;
        padding: 1px 6px;
        border-radius: 999px;
        background: var(--brand-500, #8b5cf6);
        color: #fff;
        font-size: 9px;
        font-weight: 800;
        letter-spacing: 0.04em;
        text-transform: uppercase;
        line-height: 1.5;
        vertical-align: middle;
    }

    .cmm-topbar-signin {
        display: inline-flex;
        align-items: center;
        height: 30px;
        padding: 0 14px;
        border-radius: 999px;
        border: none;
        background: var(--brand-500, #7c3aed);
        color: #fff;
        font: inherit;
        font-size: var(--fs-xs, 12px);
        font-weight: 600;
        white-space: nowrap;
        cursor: pointer;
        transition: filter var(--dur-fast) var(--ease-out);
    }
    .cmm-topbar-signin:hover { filter: brightness(1.08); }

    @media (max-width: 560px) {
        /* Icon-only pill on tiny screens to keep the topbar uncluttered */
        .cmm-upgrade-pill span { display: none; }
        .cmm-upgrade-pill { padding: 0 9px; }
    }
}

/* =============================================================
   Pro Analyst chat dock — global floating widget.
   Markup: shell/topbar.html (outside <main>, survives SPA swaps).
   Behavior: core/shell/chat-dock.js.
   Two layouts: a floating card and a docked right column that pushes
   the app content via the .cmm-shell--chat-docked grid modifier
   (mirrors how the fixed sidebar reserves its grid track).
   ============================================================= */
@layer components {

    /* ---------- Grid push: docked panel reserves a right column ---------- */
    .cmm-shell {
        --cmm-chat-dock-w: 384px;
    }
    .cmm-shell--chat-docked {
        grid-template-columns: var(--sidebar-w) 1fr var(--cmm-chat-dock-w);
        grid-template-areas:
            "sidebar topbar chat"
            "sidebar main   chat";
    }
    .cmm-shell--collapsed.cmm-shell--chat-docked {
        grid-template-columns: var(--sidebar-w-collapsed) 1fr var(--cmm-chat-dock-w);
    }

    /* ---------- Launcher bubble (FAB) ---------- */
    .cmm-chat-fab {
        position: fixed;
        right: clamp(16px, 2vw, 28px);
        bottom: clamp(16px, 2vw, 28px);
        width: 56px;
        height: 56px;
        border-radius: 50%;
        border: none;
        cursor: pointer;
        color: #fff;
        background: linear-gradient(135deg, var(--brand-500, #8b5cf6), var(--brand-700, #6d28d9));
        box-shadow: var(--elev-4, 0 20px 40px rgba(15, 23, 42, 0.12));
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 20px;
        z-index: var(--z-dropdown, 1000);
        transition: transform 0.18s var(--ease-out-soft, ease), box-shadow 0.18s ease, opacity 0.18s ease;
    }
    .cmm-chat-fab[hidden] { display: none; }
    .cmm-chat-fab:hover { transform: translateY(-2px) scale(1.04); }
    .cmm-chat-fab:active { transform: scale(0.96); }
    .cmm-chat-fab:focus-visible { outline: 2px solid var(--ring-color, var(--brand-500)); outline-offset: 3px; }
    /* Stowed while the panel is open (JS toggles this; independent of the
       pro-gating `hidden` attribute set by shell-init). */
    .cmm-chat-fab--stowed { opacity: 0; pointer-events: none; transform: scale(0.5); }
    .cmm-chat-fab__pulse {
        position: absolute;
        inset: 0;
        border-radius: 50%;
        box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand-500) 55%, transparent);
        animation: cmm-chat-pulse 2.6s ease-out infinite;
    }
    @keyframes cmm-chat-pulse {
        0%   { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand-500) 50%, transparent); }
        70%  { box-shadow: 0 0 0 14px color-mix(in srgb, var(--brand-500) 0%, transparent); }
        100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--brand-500) 0%, transparent); }
    }

    /* ---------- Panel shell ---------- */
    .cmm-chat-dock {
        position: fixed;
        display: flex;
        flex-direction: column;
        background: var(--surface-card);
        color: var(--text-primary);
        border: 1px solid var(--border-color);
        box-shadow: var(--elev-4, 0 20px 40px rgba(15, 23, 42, 0.12));
        z-index: var(--z-dropdown, 1000);
        opacity: 0;
        overflow: hidden;
        transition: opacity 0.2s var(--ease-out-soft, ease), transform 0.2s var(--ease-out-soft, ease);
    }
    .cmm-chat-dock[hidden] { display: none; }

    /* Floating card (bottom-right). */
    .cmm-chat-dock--floating {
        right: clamp(16px, 2vw, 28px);
        bottom: clamp(16px, 2vw, 28px);
        width: min(400px, calc(100vw - 32px));
        height: min(640px, calc(100vh - 120px));
        border-radius: 18px;
        transform: translateY(12px) scale(0.98);
        transform-origin: bottom right;
    }
    .cmm-chat-dock--floating.is-open { opacity: 1; transform: none; }

    /* Docked right column (full height). */
    .cmm-chat-dock--docked {
        top: 0;
        right: 0;
        bottom: 0;
        width: var(--cmm-chat-dock-w, 384px);
        height: 100vh;
        border-radius: 0;
        border-top: none;
        border-bottom: none;
        border-right: none;
        transform: translateX(16px);
    }
    .cmm-chat-dock--docked.is-open { opacity: 1; transform: none; }

    /* ---------- Header ---------- */
    .cmm-chat-dock__head {
        position: relative;
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 10px;
        padding: 12px 14px;
        border-bottom: 1px solid var(--border-color);
        flex-shrink: 0;
    }
    .cmm-chat-dock__identity { display: flex; align-items: center; gap: 10px; min-width: 0; }
    .cmm-chat-dock__avatar {
        width: 34px;
        height: 34px;
        flex-shrink: 0;
        border-radius: 10px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        color: #fff;
        font-size: 15px;
        background: linear-gradient(135deg, var(--brand-500, #8b5cf6), var(--brand-700, #6d28d9));
    }
    .cmm-chat-dock__heading { display: flex; flex-direction: column; min-width: 0; }
    .cmm-chat-dock__name { font-weight: 700; font-size: var(--fs-sm, 0.9rem); line-height: 1.2; }
    .cmm-chat-dock__status { font-size: var(--fs-xs, 0.78rem); color: var(--text-muted); }
    .cmm-chat-dock__tools { display: inline-flex; gap: 2px; flex-shrink: 0; }
    .cmm-chat-dock__tool {
        width: 30px;
        height: 30px;
        border: none;
        background: transparent;
        color: var(--text-muted);
        border-radius: 8px;
        cursor: pointer;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        transition: background 0.12s ease, color 0.12s ease;
    }
    .cmm-chat-dock__tool:hover { background: var(--surface-sunken); color: var(--text-primary); }
    .cmm-chat-dock__tool:focus-visible { outline: 2px solid var(--ring-color, var(--brand-500)); outline-offset: 1px; }

    /* ---------- Usage ring (rolling token budget) ---------- */
    /* The SVG has a viewBox but no intrinsic size; without these styles it
       renders at the default replaced-element size and breaks the header. */
    .cmm-chat-usage {
        position: relative;
        flex-shrink: 0;
        width: 30px;
        height: 30px;
        padding: 0;
        border: none;
        background: transparent;
        cursor: pointer;
        display: inline-flex;
        align-items: center;
        justify-content: center;
    }
    .cmm-chat-usage svg {
        width: 30px;
        height: 30px;
        transform: rotate(-90deg);   /* start the ring at 12 o'clock */
        transform-origin: center;
    }
    .cmm-chat-usage__track {
        fill: none;
        stroke: var(--surface-sunken, #e5e7eb);
        stroke-width: 3;
    }
    .cmm-chat-usage__value {
        fill: none;
        stroke: var(--brand-500, #8b5cf6);
        stroke-width: 3;
        stroke-linecap: round;
        stroke-dasharray: 87.96;     /* 2*pi*r, r=14 — matches chat-dock.js */
        stroke-dashoffset: 87.96;    /* start empty; JS sets offset from % used */
        transition: stroke-dashoffset 0.4s var(--ease-out-soft, ease), stroke 0.3s ease;
    }
    #cmmChatUsagePercent {
        position: absolute;
        inset: 0;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 9px;
        font-weight: 700;
        color: var(--text-secondary, var(--text-primary));
        font-variant-numeric: tabular-nums;
    }
    .cmm-chat-usage:hover .cmm-chat-usage__value { filter: brightness(1.06); }
    .cmm-chat-usage:focus-visible {
        outline: 2px solid var(--ring-color, var(--brand-500));
        outline-offset: 2px;
        border-radius: 50%;
    }

    /* Usage detail popover (toggled open from the ring) */
    .cmm-chat-usage-popover {
        position: absolute;
        top: calc(100% + 6px);
        right: 12px;
        z-index: 3;
        display: flex;
        flex-direction: column;
        gap: 3px;
        min-width: 180px;
        max-width: calc(100% - 24px);
        padding: 10px 12px;
        border-radius: 10px;
        background: var(--surface-card);
        border: 1px solid var(--border-color);
        box-shadow: var(--elev-3, 0 12px 28px rgba(15, 23, 42, 0.14));
        font-size: var(--fs-xs, 0.75rem);
    }
    .cmm-chat-usage-popover strong { font-size: var(--fs-sm, 0.85rem); color: var(--text-primary); }
    .cmm-chat-usage-popover span { color: var(--text-muted); }

    /* ---------- Conversation history (ChatGPT-style overlay) ---------- */
    /* The dock is position:fixed + overflow:hidden, so this inset:0 overlay
       anchors to it and is clipped to the rounded corners. */
    .cmm-chat-history {
        position: absolute;
        inset: 0;
        z-index: 6;
        display: flex;
        flex-direction: column;
        background: var(--surface-card);
    }
    .cmm-chat-history[hidden] { display: none; }
    .cmm-chat-history__head {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 12px 14px;
        border-bottom: 1px solid var(--border-color);
        flex-shrink: 0;
    }
    .cmm-chat-history__title {
        flex: 1 1 auto;
        font-weight: 700;
        font-size: var(--fs-sm, 0.9rem);
        color: var(--text-primary);
    }
    .cmm-chat-history__list {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        padding: 8px;
        display: flex;
        flex-direction: column;
        gap: 2px;
    }
    .cmm-chat-history__item {
        display: flex;
        align-items: center;
        gap: 4px;
        border-radius: 9px;
    }
    .cmm-chat-history__item:hover,
    .cmm-chat-history__item.is-active { background: var(--surface-sunken); }
    .cmm-chat-history__open {
        flex: 1 1 auto;
        min-width: 0;
        display: flex;
        flex-direction: column;
        gap: 1px;
        padding: 9px 10px;
        border: none;
        background: transparent;
        text-align: left;
        cursor: pointer;
        border-radius: 9px;
        color: inherit;
    }
    .cmm-chat-history__open:focus-visible { outline: 2px solid var(--ring-color, var(--brand-500)); outline-offset: -2px; }
    .cmm-chat-history__item-title {
        font-size: var(--fs-sm, 0.85rem);
        font-weight: 600;
        color: var(--text-primary);
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .cmm-chat-history__item-time { font-size: var(--fs-xs, 0.72rem); color: var(--text-muted); }
    .cmm-chat-history__del {
        flex: 0 0 auto;
        width: 30px;
        height: 30px;
        margin-right: 4px;
        border: none;
        background: transparent;
        color: var(--text-muted);
        border-radius: 8px;
        cursor: pointer;
        opacity: 0;
        transition: opacity 0.12s ease, background 0.12s ease, color 0.12s ease;
    }
    .cmm-chat-history__item:hover .cmm-chat-history__del,
    .cmm-chat-history__item:focus-within .cmm-chat-history__del { opacity: 1; }
    .cmm-chat-history__del:hover { background: rgba(220, 38, 38, 0.12); color: var(--bear, #dc2626); }
    @media (hover: none) { .cmm-chat-history__del { opacity: 0.7; } }
    .cmm-chat-history__empty,
    .cmm-chat-history__state {
        padding: 26px 16px;
        text-align: center;
        color: var(--text-muted);
        font-size: var(--fs-sm, 0.85rem);
    }

    /* ---------- Usage hard-block banner + disabled composer ---------- */
    .cmm-chat-dock__blocked {
        display: flex;
        align-items: center;
        gap: 8px;
        margin: 0 14px 8px;
        padding: 9px 12px;
        border-radius: 10px;
        font-size: var(--fs-xs, 0.78rem);
        line-height: 1.35;
        color: var(--text-secondary);
        background: color-mix(in srgb, var(--bear, #dc2626) 8%, var(--surface-sunken, transparent));
        border: 1px solid color-mix(in srgb, var(--bear, #dc2626) 30%, var(--border-color));
    }
    .cmm-chat-dock__blocked[hidden] { display: none; }
    .cmm-chat-dock__blocked i { color: var(--bear, #dc2626); flex: 0 0 auto; }
    .cmm-chat-dock__input:disabled { opacity: 0.55; cursor: not-allowed; }
    .cmm-chat-dock__send:disabled { opacity: 0.5; cursor: not-allowed; }

    /* ---------- Message log ---------- */
    .cmm-chat-dock__log {
        flex: 1 1 auto;
        min-height: 0;
        overflow-y: auto;
        padding: 14px;
        display: flex;
        flex-direction: column;
        gap: 10px;
    }
    .cmm-chat-msg {
        max-width: 90%;
        padding: 9px 12px;
        border-radius: 12px;
        line-height: 1.5;
        font-size: var(--fs-sm, 0.9rem);
    }
    .cmm-chat-msg__text { white-space: pre-wrap; word-wrap: break-word; overflow-wrap: anywhere; }
    /* Blinking caret during the word-by-word answer reveal (typeOut). */
    .cmm-chat-msg__text.is-typing::after {
        content: "";
        display: inline-block;
        width: 2px;
        height: 1em;
        margin-left: 1px;
        vertical-align: -0.15em;
        background: var(--brand-500, #8b5cf6);
        border-radius: 1px;
        animation: cmmCaretBlink 1s steps(2, start) infinite;
    }
    @keyframes cmmCaretBlink { 0%, 50% { opacity: 1; } 50.01%, 100% { opacity: 0; } }
    @media (prefers-reduced-motion: reduce) {
        .cmm-chat-msg__text.is-typing::after { animation: none; opacity: 1; }
    }
    .cmm-chat-msg--user {
        align-self: flex-end;
        background: color-mix(in srgb, var(--brand-600) 16%, transparent);
        border: 1px solid color-mix(in srgb, var(--brand-600) 24%, transparent);
        border-bottom-right-radius: 4px;
    }
    .cmm-chat-msg--agent {
        align-self: flex-start;
        background: var(--surface-sunken);
        border: 1px solid var(--border-color);
        border-bottom-left-radius: 4px;
    }
    .cmm-chat-msg--error {
        align-self: flex-start;
        background: color-mix(in srgb, var(--bear) 12%, transparent);
        border: 1px solid color-mix(in srgb, var(--bear) 28%, transparent);
        color: var(--bear-strong, #b91c1c);
    }
    .cmm-chat-msg--note {
        align-self: stretch;
        max-width: 100%;
        background: color-mix(in srgb, var(--brand-600) 7%, transparent);
        border: 1px dashed color-mix(in srgb, var(--brand-600) 26%, transparent);
        color: var(--text-secondary, var(--text-primary));
        font-size: var(--fs-xs, 0.78rem);
    }
    .cmm-chat-msg__cites {
        margin-top: 8px;
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
        font-size: var(--fs-xs, 0.74rem);
        color: var(--text-muted);
        font-family: var(--font-mono, 'JetBrains Mono', monospace);
    }
    .cmm-chat-msg__source {
        display: inline-flex;
        align-items: center;
        gap: 5px;
        padding: 2px 4px 2px 9px;
        border: 1px solid var(--border-color);
        border-radius: 999px;
        background: var(--surface-app, transparent);
        color: var(--text-secondary, var(--text-primary));
        text-decoration: none;
        transition: background 0.12s ease, border-color 0.12s ease;
    }
    .cmm-chat-msg__source:hover {
        background: color-mix(in srgb, var(--brand-600) 10%, transparent);
        border-color: color-mix(in srgb, var(--brand-600) 35%, transparent);
    }
    .cmm-chat-msg__source-sym { font-weight: 700; }
    .cmm-chat-msg__source-pct {
        font-weight: 700;
        padding: 1px 6px;
        border-radius: 999px;
        font-size: 0.92em;
    }
    .cmm-chat-msg__source-pct.is-bull { color: var(--bull, #16a34a); background: color-mix(in srgb, var(--bull, #16a34a) 14%, transparent); }
    .cmm-chat-msg__source-pct.is-bear { color: var(--bear, #dc2626); background: color-mix(in srgb, var(--bear, #dc2626) 14%, transparent); }

    /* Inline ticker links inside an answer body (e.g. "Tesla (TSLA)"). */
    .cmm-chat-ticker-link {
        color: var(--brand-700, #6d28d9);
        font-weight: 600;
        text-decoration: none;
        border-bottom: 1px solid color-mix(in srgb, var(--brand-700, #6d28d9) 35%, transparent);
    }
    .cmm-chat-ticker-link:hover {
        border-bottom-color: var(--brand-700, #6d28d9);
        background: color-mix(in srgb, var(--brand-700, #6d28d9) 8%, transparent);
    }

    /* $TICKER cashtags highlighted in the user's own message + intro tip. */
    .cmm-chat-cashtag {
        color: var(--brand-700, #6d28d9);
        font-weight: 700;
        background: color-mix(in srgb, var(--brand-500, #8b5cf6) 12%, transparent);
        border-radius: 5px;
        padding: 0 4px;
        white-space: nowrap;
    }

    /* ---------- Answer visuals: regime gauge + ticker sparklines ---------- */
    .cmm-chat-msg__visuals {
        display: flex;
        flex-wrap: wrap;
        align-items: center;
        gap: 8px;
        margin-top: 10px;
    }
    .cmm-chat-gauge {
        display: inline-flex;
        align-items: center;
        gap: 7px;
        padding: 4px 10px;
        border-radius: 999px;
        border: 1px solid transparent;
        font-size: var(--fs-xs, 0.75rem);
        font-weight: 700;
    }
    .cmm-chat-gauge__label { display: inline-flex; align-items: center; gap: 5px; text-transform: uppercase; letter-spacing: 0.02em; }
    .cmm-chat-gauge__label i { font-size: 0.95em; }
    .cmm-chat-gauge__bars { display: inline-flex; gap: 2px; }
    .cmm-chat-gauge__seg { width: 5px; height: 11px; border-radius: 2px; background: var(--border-color); }
    .cmm-chat-gauge__score { color: var(--text-muted); font-weight: 600; }
    .cmm-chat-gauge--up      { color: var(--bull, #16a34a); background: color-mix(in srgb, var(--bull, #16a34a) 12%, transparent); border-color: color-mix(in srgb, var(--bull, #16a34a) 30%, transparent); }
    .cmm-chat-gauge--up .cmm-chat-gauge__seg.is-on      { background: var(--bull, #16a34a); }
    .cmm-chat-gauge--down    { color: var(--bear, #dc2626); background: color-mix(in srgb, var(--bear, #dc2626) 12%, transparent); border-color: color-mix(in srgb, var(--bear, #dc2626) 30%, transparent); }
    .cmm-chat-gauge--down .cmm-chat-gauge__seg.is-on    { background: var(--bear, #dc2626); }
    .cmm-chat-gauge--neutral { color: #b45309; background: color-mix(in srgb, #f59e0b 14%, transparent); border-color: color-mix(in srgb, #f59e0b 34%, transparent); }
    .cmm-chat-gauge--neutral .cmm-chat-gauge__seg.is-on { background: #f59e0b; }

    .cmm-chat-spark {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 3px 9px;
        border-radius: 10px;
        border: 1px solid var(--border-color);
        background: var(--surface-app, transparent);
        font-size: var(--fs-xs, 0.75rem);
    }
    .cmm-chat-spark--pending { display: none; }   /* hidden until its series loads */
    .cmm-chat-spark__logo {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        width: 18px;
        height: 18px;
        flex-shrink: 0;
        border-radius: 5px;
        color: #fff;
        font-size: 10px;
        font-weight: 800;
        line-height: 1;
    }
    .cmm-chat-spark__sym { font-weight: 700; color: var(--text-secondary, var(--text-primary)); }
    .cmm-chat-spark__svg { width: 56px; height: 20px; flex-shrink: 0; }
    .cmm-chat-spark__pct { font-weight: 700; font-variant-numeric: tabular-nums; }
    .cmm-chat-spark--bull { color: var(--bull, #16a34a); }
    .cmm-chat-spark--bear { color: var(--bear, #dc2626); }
    .cmm-chat-inline-btn {
        margin-top: 8px;
        display: inline-block;
        padding: 6px 12px;
        border: none;
        border-radius: 8px;
        font-weight: 600;
        font-size: var(--fs-xs, 0.78rem);
        cursor: pointer;
        color: #fff;
        background: var(--brand-600, #7c3aed);
    }

    /* Typing indicator (three bouncing dots) */
    .cmm-chat-dots { display: inline-flex; gap: 4px; align-items: center; padding: 2px 0; }
    .cmm-chat-dots span {
        width: 7px;
        height: 7px;
        border-radius: 50%;
        background: var(--text-muted);
        animation: cmm-chat-bounce 1.2s infinite ease-in-out;
    }
    .cmm-chat-dots span:nth-child(2) { animation-delay: 0.15s; }
    .cmm-chat-dots span:nth-child(3) { animation-delay: 0.3s; }
    @keyframes cmm-chat-bounce {
        0%, 80%, 100% { transform: translateY(0); opacity: 0.4; }
        40% { transform: translateY(-4px); opacity: 1; }
    }

    /* ---------- Context pill ("the news you're on") ----------
       A small VS Code-style toggle chip: paperclip + ticker + a tick when
       attached. Click toggles attach/detach; detached = muted outline that
       can be re-enabled. */
    .cmm-chat-dock__context {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        margin: 8px 14px 0;
        padding: 4px 10px;
        border-radius: 999px;
        width: fit-content;
        max-width: calc(100% - 28px);
        font-size: var(--fs-xs, 0.78rem);
        line-height: 1.4;
        cursor: pointer;
        background: color-mix(in srgb, var(--brand-600) 14%, transparent);
        border: 1px solid color-mix(in srgb, var(--brand-600) 34%, transparent);
        color: var(--brand-700, #4f46e5);
        transition: background var(--dur-fast, 0.14s) var(--ease-out, ease),
                    border-color var(--dur-fast, 0.14s) var(--ease-out, ease),
                    color var(--dur-fast, 0.14s) var(--ease-out, ease),
                    opacity var(--dur-fast, 0.14s) var(--ease-out, ease);
        animation: cmmContextPop var(--dur, 0.18s) var(--ease-out, ease);
    }
    .cmm-chat-dock__context[hidden] { display: none; }
    .cmm-chat-dock__context:hover { background: color-mix(in srgb, var(--brand-600) 21%, transparent); }
    .cmm-chat-dock__context > i { font-size: 0.72em; flex-shrink: 0; }
    .cmm-chat-dock__context-text {
        font-family: var(--font-mono, monospace);
        font-weight: 600;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
    }
    .cmm-chat-dock__context-tick { font-size: 0.66em; opacity: 0.85; }
    /* Detached: muted outline, tick hidden — click re-attaches. */
    .cmm-chat-dock__context.is-detached {
        background: transparent;
        border-color: var(--border-color, rgba(0,0,0,0.16));
        color: var(--text-muted);
        opacity: 0.85;
    }
    .cmm-chat-dock__context.is-detached:hover { opacity: 1; color: var(--text-secondary, var(--text-primary)); }
    .cmm-chat-dock__context.is-detached .cmm-chat-dock__context-tick { display: none; }
    @keyframes cmmContextPop {
        from { opacity: 0; transform: translateY(3px); }
        to   { opacity: 1; transform: translateY(0); }
    }
    @media (prefers-reduced-motion: reduce) {
        .cmm-chat-dock__context { animation: none; }
    }

    /* ---------- Suggestion chips ---------- */
    .cmm-chat-dock__suggest {
        display: flex;
        flex-wrap: wrap;
        gap: 6px;
        padding: 10px 14px 4px;
    }
    .cmm-chat-dock__suggest:empty { display: none; }
    .cmm-chat-chip {
        border: 1px solid var(--border-color);
        background: var(--surface-app, transparent);
        color: var(--text-secondary, var(--text-primary));
        border-radius: 999px;
        padding: 6px 11px;
        font-size: var(--fs-xs, 0.78rem);
        cursor: pointer;
        text-align: left;
        line-height: 1.3;
        transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease;
    }
    .cmm-chat-chip:hover {
        background: color-mix(in srgb, var(--brand-600) 10%, transparent);
        border-color: color-mix(in srgb, var(--brand-600) 35%, transparent);
        color: var(--text-primary);
    }

    /* ---------- Composer ---------- */
    .cmm-chat-dock__form {
        display: flex;
        align-items: flex-end;
        gap: 8px;
        padding: 10px 14px 6px;
    }
    .cmm-chat-dock__input {
        flex: 1;
        resize: none;
        min-height: 40px;
        max-height: 120px;
        padding: 9px 12px;
        border-radius: 12px;
        border: 1px solid var(--border-color);
        background: var(--surface-sunken);
        color: var(--text-primary);
        font-family: inherit;
        font-size: var(--fs-sm, 0.9rem);
        line-height: 1.4;
    }
    .cmm-chat-dock__input:focus { outline: none; border-color: var(--brand-500); }
    .cmm-chat-dock__input:disabled { opacity: 0.6; }
    .cmm-chat-dock__send {
        flex-shrink: 0;
        width: 40px;
        height: 40px;
        border-radius: 12px;
        border: none;
        cursor: pointer;
        color: #fff;
        background: var(--brand-600, #7c3aed);
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 15px;
        transition: background 0.12s ease, opacity 0.12s ease;
    }
    .cmm-chat-dock__send:hover { background: var(--brand-700, #6d28d9); }
    .cmm-chat-dock__send:disabled { opacity: 0.5; cursor: wait; }
    .cmm-chat-dock__hint {
        padding: 0 14px 12px;
        font-size: 11px;
        color: var(--text-muted);
        text-align: center;
    }

    /* ---------- Pro paywall (free / guest members) ----------
       Vance is Pro-only. The launcher (FAB) stays visible to every signed-in
       member, but opening the dock without Pro shows this upgrade screen
       instead of a usable chat. The backend is the source of truth — every
       analyst route returns a 403 pro_feature_required for non-Pro — so this
       just mirrors that gate so a free user never sees a composer that would
       only fail on send. Toggled by the .cmm-chat-dock--locked class. */
    .cmm-chat-dock--locked .cmm-chat-dock__log,
    .cmm-chat-dock--locked .cmm-chat-dock__suggest,
    .cmm-chat-dock--locked .cmm-chat-dock__context,
    .cmm-chat-dock--locked .cmm-chat-dock__blocked,
    .cmm-chat-dock--locked .cmm-chat-dock__form,
    .cmm-chat-dock--locked .cmm-chat-dock__hint,
    .cmm-chat-dock--locked .cmm-chat-usage,
    /* Per-conversation tools (and the history overlay) are meaningless without
       access — suppress them so the upgrade screen fully replaces the chat UI.
       Keep Dock-to-side + Close. */
    .cmm-chat-dock--locked .cmm-chat-history,
    .cmm-chat-dock--locked .cmm-chat-dock__tool[data-cmm-action="new-chat-dock"],
    .cmm-chat-dock--locked .cmm-chat-dock__tool[data-cmm-action="toggle-chat-history"] { display: none !important; }

    .cmm-chat-dock__paywall { display: none; }
    .cmm-chat-dock--locked .cmm-chat-dock__paywall {
        flex: 1 1 auto;
        min-height: 0;
        display: flex;
        flex-direction: column;
        align-items: center;
        justify-content: center;
        text-align: center;
        gap: 12px;
        padding: 24px 26px;
    }
    .cmm-chat-dock__paywall-icon {
        width: 56px;
        height: 56px;
        border-radius: 16px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        font-size: 24px;
        color: #fff;
        background: linear-gradient(135deg, var(--brand-500, #8b5cf6), var(--brand-700, #6d28d9));
        box-shadow: var(--elev-2, 0 8px 20px rgba(124, 58, 237, 0.35));
    }
    .cmm-chat-dock__paywall-title {
        margin: 4px 0 0;
        font-size: 1.05rem;
        font-weight: 700;
        color: var(--text-primary);
    }
    .cmm-chat-dock__paywall-text {
        margin: 0;
        max-width: 280px;
        font-size: var(--fs-sm, 0.9rem);
        line-height: 1.5;
        color: var(--text-muted);
    }
    .cmm-chat-dock__paywall-btn {
        margin-top: 6px;
        padding: 10px 20px;
        border: none;
        border-radius: 12px;
        cursor: pointer;
        font-weight: 600;
        font-size: var(--fs-sm, 0.9rem);
        color: #fff;
        background: var(--brand-600, #7c3aed);
        transition: background 0.12s ease, transform 0.12s ease;
    }
    .cmm-chat-dock__paywall-btn:hover { background: var(--brand-700, #6d28d9); transform: translateY(-1px); }
    .cmm-chat-dock__paywall-btn:focus-visible { outline: 2px solid var(--ring-color, var(--brand-500)); outline-offset: 2px; }

    /* ---------- Mobile: both layouts become a bottom sheet overlay ---------- */
    @media (max-width: 1023px) {
        /* The mobile grid is single-column; never reserve a chat track. */
        .cmm-shell--chat-docked,
        .cmm-shell--collapsed.cmm-shell--chat-docked {
            grid-template-columns: 1fr;
            grid-template-areas: "topbar" "main";
        }
        .cmm-chat-dock--floating,
        .cmm-chat-dock--docked {
            top: auto;
            right: 0;
            left: 0;
            bottom: 0;
            width: 100%;
            height: min(86vh, 640px);
            border-radius: 18px 18px 0 0;
            border-right: 1px solid var(--border-color);
            border-bottom: none;
            transform: translateY(16px);
            transform-origin: bottom center;
        }
        .cmm-chat-dock--floating.is-open,
        .cmm-chat-dock--docked.is-open { transform: none; }
    }

    @media (prefers-reduced-motion: reduce) {
        .cmm-chat-fab, .cmm-chat-fab__pulse, .cmm-chat-dock,
        .cmm-chat-dots span { transition: none; animation: none; }
    }

    /* ---------------------------------------------------------------
       Shared ticker affordance (window.cmmTicker, core/shell/ticker.js)
       Canonical home so the hover "add / remove to watchlist" chip is
       styled on EVERY surface — news, performance, analysis, saved,
       chat, etc. (dashboard-v2.css keeps an identical copy for pages
       that predate this; both live in @layer components so they agree).
       .cmm-ticker hosts the symbol text + a button that slides in on
       hover; .is-watchlisted shows a persistent green check (red on
       hover = click to remove).
       --------------------------------------------------------------- */
    .cmm-ticker { display: inline-flex; align-items: center; position: relative; }
    .cmm-ticker-add {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        flex: none;
        width: 0;
        height: 16px;
        margin-left: 0;
        padding: 0;
        border: none;
        border-radius: 50%;
        background: var(--brand-600, #6366f1);
        color: #fff;
        font-size: 9px;
        line-height: 1;
        cursor: pointer;
        overflow: hidden;
        opacity: 0;
        transition: width var(--dur-fast, .16s) var(--ease-out, ease), margin var(--dur-fast, .16s) var(--ease-out, ease), opacity var(--dur-fast, .16s) var(--ease-out, ease), background var(--dur-fast, .16s) var(--ease-out, ease);
    }
    .cmm-ticker:hover .cmm-ticker-add,
    .cmm-ticker-add:focus-visible { width: 16px; margin-left: 6px; opacity: 1; }
    .cmm-ticker-add:hover { background: var(--brand-700, #4f46e5); }
    .cmm-ticker-add.is-watchlisted { width: 16px; margin-left: 6px; opacity: 1; background: var(--bull, #10b981); }
    .cmm-ticker:hover .cmm-ticker-add.is-watchlisted { background: var(--bear, #ef4444); }
    .cmm-ticker-add.is-error { width: 16px; margin-left: 6px; opacity: 1; background: var(--bear, #ef4444); }

    @media (prefers-reduced-motion: reduce) {
        .cmm-ticker-add { transition: none; }
    }
}

/* ---------------------------------------------------------------
   Feedback survey card (window.cmmFeedbackSurvey, core/shell/feedback-survey.js)
   Body-level, fixed bottom-right. bottom: 88px clears the chat FAB
   (56px + up to 28px offset); z-index sits above the dock and below
   toasts (10060) so "Thanks — sent" can land on top of it.
   Visibility is the `hidden` attribute only (body.cmm-app [hidden]
   above). Colors have UNLAYERED dark twins in theme-dark.css because
   its global reset forces `color: inherit` on p/label/h2 and beats
   anything declared inside this layer.
   --------------------------------------------------------------- */
@layer components {
    .cmm-feedback-card {
        position: fixed;
        right: clamp(16px, 2vw, 28px);
        bottom: 88px;
        z-index: 10050;
        width: min(360px, calc(100vw - 32px));
        max-width: 360px;
        padding: 18px 18px 16px;
        background: var(--surface-card, #fff);
        color: var(--text-primary, #0f172a);
        border: 1px solid var(--border-color, #e5e7eb);
        border-radius: 16px;
        box-shadow: var(--elev-3, 0 24px 64px rgba(15, 23, 42, 0.18));
        font-size: var(--fs-sm, 0.875rem);
        line-height: 1.45;
        animation: cmm-feedback-in 0.22s var(--ease-out, ease);
    }
    @keyframes cmm-feedback-in {
        from { opacity: 0; transform: translateY(10px); }
        to   { opacity: 1; transform: none; }
    }
    @media (prefers-reduced-motion: reduce) {
        .cmm-feedback-card { animation: none; }
    }
    .cmm-feedback-card.is-busy { opacity: 0.8; }

    .cmm-feedback-card__close {
        position: absolute;
        top: 10px;
        right: 10px;
        width: 28px;
        height: 28px;
        display: inline-flex;
        align-items: center;
        justify-content: center;
        border: 0;
        border-radius: 8px;
        background: transparent;
        color: var(--text-muted, #64748b);
        font-size: 13px;
        cursor: pointer;
    }
    .cmm-feedback-card__close:hover {
        background: var(--surface-sunken, rgba(148, 163, 184, 0.14));
        color: var(--text-primary, #0f172a);
    }
    .cmm-feedback-card__close:focus-visible,
    .cmm-feedback-card__choice:focus-visible,
    .cmm-feedback-card__reason:focus-visible,
    .cmm-feedback-btn:focus-visible,
    .cmm-feedback-card__title:focus-visible {
        outline: 2px solid var(--brand-500, #7c3aed);
        outline-offset: 2px;
    }

    .cmm-feedback-card__title {
        margin: 0 28px 4px 0;
        font-size: var(--fs-md, 1rem);
        font-weight: 700;
        line-height: 1.3;
        color: var(--text-primary, #0f172a);
    }
    .cmm-feedback-card__title:focus { outline: none; }
    .cmm-feedback-card__sub {
        margin: 0 0 14px;
        color: var(--text-secondary, #475569);
    }

    /* Step 1: five word chips. A 30% basis wraps them 3 + 2 at the card's
       324px inner width ("Not great" does not fit five-up) and the last two
       grow to share their row. Text only — no icon slot. */
    .cmm-feedback-card__choices {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
    }
    .cmm-feedback-card__choice,
    .cmm-feedback-card__reason {
        display: inline-flex;
        align-items: center;
        justify-content: center;
        padding: 10px 12px;
        border: 1px solid var(--border-color, #e5e7eb);
        border-radius: 12px;
        background: var(--surface-app, transparent);
        color: var(--text-primary, #0f172a);
        font: inherit;
        font-weight: 600;
        line-height: 1.25;
        cursor: pointer;
        transition: border-color var(--dur-fast, .16s) var(--ease-out, ease),
                    background var(--dur-fast, .16s) var(--ease-out, ease);
    }
    .cmm-feedback-card__choice {
        flex: 1 1 30%;
        white-space: nowrap;
    }
    .cmm-feedback-card__choice:hover,
    .cmm-feedback-card__reason:hover {
        border-color: var(--brand-300, #c4b5fd);
        background: var(--surface-sunken, rgba(148, 163, 184, 0.1));
    }
    .cmm-feedback-card__choice[aria-checked="true"],
    .cmm-feedback-card__reason[aria-checked="true"] {
        border-color: var(--brand-600, #7c3aed);
        background: var(--brand-50, rgba(124, 58, 237, 0.1));
    }
    .cmm-feedback-card__choice:active,
    .cmm-feedback-card__reason:active { transform: scale(0.98); }

    /* Step 2: one reason chip per row-wrap, natural width, a size down. */
    .cmm-feedback-card__reasons {
        display: flex;
        flex-wrap: wrap;
        gap: 8px;
        margin-bottom: 12px;
    }
    .cmm-feedback-card__reason {
        flex: 0 1 auto;
        padding: 7px 11px;
        border-radius: 999px;
        font-size: 0.8125rem;
        font-weight: 500;
        text-align: left;
    }

    .cmm-feedback-card__text {
        display: block;
        width: 100%;
        box-sizing: border-box;
        resize: vertical;
        min-height: 72px;
        padding: 9px 12px;
        border: 1px solid var(--border-color, #e5e7eb);
        border-radius: 10px;
        background: var(--surface-app, transparent);
        color: var(--text-primary, #0f172a);
        font: inherit;
        font-size: var(--fs-sm, 0.875rem);
    }
    .cmm-feedback-card__text::placeholder { color: var(--text-muted, #94a3b8); }
    .cmm-feedback-card__text:focus { outline: none; border-color: var(--brand-600, #7c3aed); }
    .cmm-feedback-card__count {
        margin: 4px 0 10px;
        text-align: right;
        font-size: 0.72rem;
        color: var(--text-muted, #64748b);
        font-variant-numeric: tabular-nums;
    }

    .cmm-feedback-card__consent {
        display: flex;
        align-items: center;
        gap: 8px;
        margin: 0;
        font-weight: 600;
        color: var(--text-primary, #0f172a);
        cursor: pointer;
    }
    .cmm-feedback-card__consent input {
        margin: 0;
        width: 16px;
        height: 16px;
        accent-color: var(--brand-600, #7c3aed);
        cursor: pointer;
    }
    .cmm-feedback-card__helper {
        margin: 3px 0 14px 24px;
        font-size: 0.78rem;
        color: var(--text-muted, #64748b);
    }

    .cmm-feedback-card__actions {
        display: flex;
        justify-content: flex-end;
        gap: 8px;
    }
    /* Twins of settings.css .settings-btn--primary/--ghost; settings.css is a
       page stylesheet, so the card carries its own copy for every shell page. */
    .cmm-feedback-btn {
        display: inline-flex;
        align-items: center;
        gap: 6px;
        padding: 9px 14px;
        border-radius: 10px;
        font: inherit;
        font-size: var(--fs-sm, 0.875rem);
        font-weight: 600;
        cursor: pointer;
        border: 1px solid transparent;
        white-space: nowrap;
        transition: background var(--dur-fast, .16s) var(--ease-out, ease),
                    border-color var(--dur-fast, .16s) var(--ease-out, ease),
                    color var(--dur-fast, .16s) var(--ease-out, ease),
                    box-shadow var(--dur-fast, .16s) var(--ease-out, ease);
    }
    .cmm-feedback-btn:active { transform: scale(0.97); }
    .cmm-feedback-btn:disabled { cursor: default; opacity: 0.7; }
    .cmm-feedback-btn--primary {
        background: var(--brand-600, #7c3aed);
        color: #fff;
    }
    .cmm-feedback-btn--primary:hover:not(:disabled) {
        background: var(--brand-700, #6d28d9);
        box-shadow: var(--elev-2, 0 6px 16px rgba(15, 23, 42, 0.12));
    }
    .cmm-feedback-btn--ghost {
        background: transparent;
        color: var(--text-secondary, #475569);
        border-color: var(--border-color, #e5e7eb);
    }
    .cmm-feedback-btn--ghost:hover:not(:disabled) {
        background: var(--surface-sunken, rgba(148, 163, 184, 0.1));
        color: var(--text-primary, #0f172a);
        border-color: var(--brand-300, #c4b5fd);
    }

    /* Admin-only feedback rows in the topbar bell: a violet comment badge
       beside the signup (green) and trade (robot) rows. */
    .cmm-alertmodal__notif-icon--feedback {
        flex: 0 0 auto;
        width: 26px;
        height: 26px;
        display: flex;
        align-items: center;
        justify-content: center;
        border-radius: 8px;
        font-size: 12px;
        margin-top: 1px;
        color: var(--brand-600, #6d28d9);
        background: var(--brand-50, rgba(124, 58, 237, 0.12));
    }
    html.theme-dark .cmm-alertmodal__notif-icon--feedback {
        color: #c4b5fd;
        background: rgba(124, 58, 237, 0.18);
    }

    @media (max-width: 640px) {
        .cmm-feedback-card { right: 12px; left: 12px; width: auto; max-width: none; }
    }
}

/* Legacy theme.css has unlayered span colors. Keep this label readable there too. */
body.cmm-app .cmm-pro-mark { color: #92400e; }
html.theme-dark body.cmm-app .cmm-pro-mark { color: #d6b47a; }
