Resolve B-98 visual review deviations and B-97 atomicity finding: - Scoped mentorView header to title/subtitle + theme toggle only (hides date, refresh, background refresh, system management and account menus). - Map contact avatars by stable id to the final day/night palette (52科比 and self stay blue; others use the final violet/green/orange/red/teal/ purple/yellow tones). - Grade badges read A级/B级/C级; pinned contacts render a pin + 置顶 badge; row-side pin controls are removed (chat header keeps pinning). - Chat header drops grade badges; subtitle shows the active contact description/tagline. - Assistant message column caps at 900px and centers on wide screens; user bubble keeps its 60% cap. - Widen the directory search field (~218px target), keep filter/sort on the same row, and make the filter button icon-only (no chevron). - Follow-up links drop the leading icon; no '日期 · 回答完成' meta line; follow-up divider is 382px and left-aligned with the text column. - Own-message meta shows time only; composer height converges to ~85px while keeping auto-grow and the 168px cap. - Selected contact right inset ~10px, header action radius 8px, and a thin list scrollbar instead of the reserved gutter. - Remove the iFinD settings switch fragment from index.html so the mentor commit no longer carries half of the parallel iFinD work; the id contract test now tolerates dangling references introduced only by uncommitted working-tree edits. - Add contract + e2e assertions for the header visibility, avatar tone mapping, badge copy, chat subtitle, message max-width, composer height, and follow-up area. Co-authored-by: multica-agent <github@multica.ai>
469 lines
15 KiB
CSS
469 lines
15 KiB
CSS
/*
|
|
* Canonical frontend tokens.
|
|
*
|
|
* Ownership flows in one direction:
|
|
* primitive values -> semantic meaning -> component contracts.
|
|
* Historical variable names remain aliases so page CSS can migrate without
|
|
* changing the rendered interface.
|
|
*/
|
|
|
|
:root {
|
|
color-scheme: light;
|
|
|
|
/* Primitive tokens */
|
|
--color-white: #ffffff;
|
|
--color-gray-25: #fcfcfd;
|
|
--color-gray-50: #f8f9fb;
|
|
--color-gray-100: #f3f4f6;
|
|
--color-gray-200: #e5e7eb;
|
|
--color-gray-300: #d1d5db;
|
|
--color-gray-500: #6b7280;
|
|
--color-gray-700: #374151;
|
|
--color-gray-900: #1f2937;
|
|
--color-shell-canvas: #f4f5f7;
|
|
--color-page-canvas: #f4f5f7;
|
|
--color-surface-muted: #f3f4f6;
|
|
--color-surface-subtle: #f8fafc;
|
|
--color-border: #e5e7eb;
|
|
--color-border-strong: #d1d5db;
|
|
--color-text-primary: #1f2937;
|
|
--color-text-secondary: #6b7280;
|
|
--color-text-tertiary: #9ca3af;
|
|
--color-action-base: #2563eb;
|
|
--color-action-base-hover: #1d4ed8;
|
|
--color-action-base-soft: #eff4ff;
|
|
--color-action: #2563eb;
|
|
--color-action-hover: #1d4ed8;
|
|
--color-action-soft: #eff4ff;
|
|
--color-action-line: #c7d8fb;
|
|
--color-market-up-base: #e04536;
|
|
--color-market-up-base-soft: #fdecea;
|
|
--color-market-up: #e04536;
|
|
--color-market-up-soft: #fdecea;
|
|
--color-market-down-base: #16a34a;
|
|
--color-market-down-base-soft: #e9f7ee;
|
|
--color-market-down: #16a34a;
|
|
--color-market-down-soft: #e9f7ee;
|
|
--color-warning-base: #b45309;
|
|
--color-warning-base-soft: #fdf3e3;
|
|
--color-warning: #b45309;
|
|
--color-warning-soft: #fdf3e3;
|
|
|
|
--size-radius-sm: 5px;
|
|
--size-radius-md: 7px;
|
|
--size-radius-lg: 10px;
|
|
--size-control: 32px;
|
|
--size-sidebar: 200px;
|
|
--size-topbar: 46px;
|
|
--size-summary: 36px;
|
|
--size-statusbar: 30px;
|
|
--size-page-pad-y: 14px;
|
|
--size-page-pad-x: 16px;
|
|
--size-card-gap: 12px;
|
|
|
|
--elevation-card: 0 1px 2px rgba(16, 24, 40, .05);
|
|
--elevation-soft: 0 1px 2px rgba(16, 24, 40, .05);
|
|
--elevation-raised: 0 4px 14px rgba(16, 24, 40, .06);
|
|
--elevation-float: 0 12px 32px rgba(0, 0, 0, .18);
|
|
--motion-instant: 100ms;
|
|
--motion-fast: 140ms;
|
|
--motion-medium: 200ms;
|
|
--motion-deliberate: 260ms;
|
|
--motion-slow: 560ms;
|
|
--ease-out: cubic-bezier(0.22, 1, 0.36, 1);
|
|
|
|
/* Semantic tokens */
|
|
--canvas: var(--color-shell-canvas);
|
|
--surface: var(--color-white);
|
|
--surface-muted: var(--color-surface-muted);
|
|
--surface-subtle: var(--color-surface-subtle);
|
|
--surface-canvas: var(--color-page-canvas);
|
|
--surface-raised: var(--color-white);
|
|
--surface-sunken: #eef0f3;
|
|
--surface-hover: #f8faff;
|
|
--surface-selected: #eff4ff;
|
|
--surface-overlay: var(--color-white);
|
|
--border: var(--color-border);
|
|
--border-strong: var(--color-border-strong);
|
|
--border-subtle: #eef0f3;
|
|
--text-primary: var(--color-text-primary);
|
|
--text-secondary: var(--color-text-secondary);
|
|
--text-tertiary: var(--color-text-tertiary);
|
|
--text-inverse: #ffffff;
|
|
--on-action: #ffffff;
|
|
--action: var(--color-action-base);
|
|
--action-hover: var(--color-action-base-hover);
|
|
--action-soft: var(--color-action-base-soft);
|
|
--market-up: var(--color-market-up-base);
|
|
--market-up-soft: var(--color-market-up-base-soft);
|
|
--market-down: var(--color-market-down-base);
|
|
--market-down-soft: var(--color-market-down-base-soft);
|
|
--warning-color: var(--color-warning-base);
|
|
--warning-soft: var(--color-warning-base-soft);
|
|
--control-surface: var(--surface-raised);
|
|
--control-hover: var(--surface-hover);
|
|
--control-border: var(--border-strong);
|
|
--table-header: var(--surface-subtle);
|
|
--table-hover: #f8faff;
|
|
--table-selected: var(--surface-selected);
|
|
--focus-ring: rgba(37, 99, 235, .16);
|
|
--backdrop: rgba(17, 24, 39, .48);
|
|
--primary: var(--color-action);
|
|
--primary-hover: var(--color-action-hover);
|
|
--danger: var(--color-market-up);
|
|
--success: var(--color-market-down);
|
|
--warning: var(--color-warning);
|
|
|
|
/* Component tokens */
|
|
--card-bg: var(--surface-raised);
|
|
--card-border: var(--border);
|
|
--card-radius: var(--size-radius-lg);
|
|
--card-shadow: var(--elevation-card);
|
|
--control-height: var(--size-control);
|
|
--page-gap: var(--size-card-gap);
|
|
--radius-sm: var(--size-radius-sm);
|
|
--radius-md: var(--size-radius-md);
|
|
--radius-lg: var(--size-radius-lg);
|
|
--shadow-xs: var(--elevation-card);
|
|
--shadow-sm: var(--elevation-raised);
|
|
--shadow-float: var(--elevation-float);
|
|
--duration-fast: 150ms;
|
|
--duration-normal: 220ms;
|
|
|
|
--font-size-aux: 10.5px;
|
|
--font-size-caption: 11px;
|
|
--font-size-label: 12px;
|
|
--font-size-table: 12.5px;
|
|
--font-size-body: 13px;
|
|
--font-size-card-title: 14px;
|
|
--font-size-page-title: 17px;
|
|
--font-size-metric: 22px;
|
|
--font-weight-regular: 400;
|
|
--font-weight-medium: 500;
|
|
--font-weight-semibold: 600;
|
|
--font-weight-bold: 700;
|
|
|
|
--space-4: 4px;
|
|
--space-8: 8px;
|
|
--space-12: 12px;
|
|
--space-16: 16px;
|
|
--space-24: 24px;
|
|
|
|
--sidebar-width: var(--size-sidebar);
|
|
--sidebar-compact-width: 64px;
|
|
--topbar-height: var(--size-topbar);
|
|
--summary-height: var(--size-summary);
|
|
--statusbar-height: var(--size-statusbar);
|
|
--page-pad-y: var(--size-page-pad-y);
|
|
--page-pad-x: var(--size-page-pad-x);
|
|
--card-gap: var(--size-card-gap);
|
|
--workspace-height: calc(100vh - var(--topbar-height) - var(--statusbar-height));
|
|
--content-height: calc(var(--workspace-height) - var(--summary-height));
|
|
--table-wide: 1180px;
|
|
--table-medium: 930px;
|
|
--table-compact: 720px;
|
|
--col-rank: 44px;
|
|
--col-date: 94px;
|
|
--col-stock: 160px;
|
|
--col-number: 96px;
|
|
--col-action: 96px;
|
|
--col-text: 220px;
|
|
--right-rail-wide: 372px;
|
|
--pool-table-max-height: calc(var(--content-height) - var(--topbar-height) - var(--page-pad-y) - var(--page-pad-y) - var(--card-gap));
|
|
--sentiment-history-max-height: 510px;
|
|
--sentiment-history-min-height: 220px;
|
|
--primary-share: 1.45fr;
|
|
--secondary-share: .75fr;
|
|
--mobile-nav-height: 64px;
|
|
--mobile-header-height: 52px;
|
|
--mobile-tab-height: 56px;
|
|
--mobile-touch-size: 44px;
|
|
--mobile-date-width: 116px;
|
|
--mobile-nav-icon-size: 20px;
|
|
--mobile-chart-height: 240px;
|
|
--mobile-table-min-height: 260px;
|
|
--mobile-phase-badge-width: 88px;
|
|
--mobile-summary-card-width: 124px;
|
|
--mobile-shell-pad: var(--space-8);
|
|
--mobile-page-pad: var(--space-12);
|
|
--mobile-min-width: 320px;
|
|
--mobile-safe-bottom: env(safe-area-inset-bottom, 0px);
|
|
--mobile-content-bottom: calc(var(--mobile-nav-height) + var(--mobile-safe-bottom) + var(--mobile-page-pad));
|
|
--mobile-layer-header: 50;
|
|
--mobile-layer-nav: 70;
|
|
--mobile-layer-menu: 80;
|
|
--mobile-layer-backdrop: 75;
|
|
--font-aux: var(--font-size-aux);
|
|
|
|
--dragon-profile-list-width: 340px;
|
|
--dragon-profile-detail-min-height: 460px;
|
|
--dragon-profile-list-max-height: 320px;
|
|
--dragon-profile-row-min-height: 64px;
|
|
--dragon-profile-row-avatar-size: 36px;
|
|
--dragon-profile-avatar-size: 72px;
|
|
--dragon-profile-control-height: 33px;
|
|
--dragon-profile-gap: 12px;
|
|
--dragon-profile-panel-padding: 16px;
|
|
--dragon-profile-row-padding: 10px 12px;
|
|
--dragon-profile-title-font: 18px;
|
|
--dragon-profile-name-font: 13px;
|
|
--dragon-profile-body-font: 12px;
|
|
--dragon-profile-meta-font: 11px;
|
|
--dragon-profile-transition: 160ms ease;
|
|
--dragon-profile-border-width: 1px;
|
|
--dragon-profile-focus-width: 2px;
|
|
--dragon-profile-focus-offset: -2px;
|
|
--dragon-profile-radius-inset: 2px;
|
|
--dragon-profile-body-line-height: 1.75;
|
|
--dragon-profile-icon-stroke: 1;
|
|
--dragon-profile-weight-strong: 750;
|
|
--dragon-profile-weight-semibold: 600;
|
|
|
|
--mentor-directory-width: 300px;
|
|
--mentor-pane-header-height: 60px;
|
|
--mentor-avatar-size: 42px;
|
|
--mentor-profile-avatar-size: 68px;
|
|
--mentor-composer-min-height: 85px;
|
|
--mentor-message-max-width: 60%;
|
|
|
|
--chart-background: #fbfcfd;
|
|
--chart-grid: #e2e8ec;
|
|
--chart-axis: #6c7983;
|
|
--chart-zero: #aeb7c1;
|
|
--chart-line: #1d65c1;
|
|
--chart-average: #b7791f;
|
|
--chart-up: #c93f45;
|
|
--chart-down: #087a55;
|
|
--chart-up-volume: rgba(201, 63, 69, .58);
|
|
--chart-down-volume: rgba(8, 122, 85, .58);
|
|
--chart-area: rgba(37, 99, 235, .07);
|
|
--chart-alert-area: rgba(224, 69, 54, .05);
|
|
--chart-moving-average: #d1d5db;
|
|
--chart-repair: #f59e0b;
|
|
--chart-ma-10: #a76500;
|
|
--chart-ma-20: #626c78;
|
|
|
|
/* Compatibility aliases. Do not add new usage of these names. */
|
|
--xb-gray-25: var(--color-gray-25);
|
|
--xb-gray-50: var(--color-gray-50);
|
|
--xb-gray-100: var(--color-gray-100);
|
|
--xb-gray-200: var(--color-gray-200);
|
|
--xb-gray-300: var(--color-gray-300);
|
|
--xb-gray-500: var(--color-gray-500);
|
|
--xb-gray-700: var(--color-gray-700);
|
|
--xb-gray-900: var(--color-gray-900);
|
|
--xb-blue-50: #eef4ff;
|
|
--xb-blue-100: #dce8ff;
|
|
--xb-blue-500: var(--color-action);
|
|
--xb-blue-600: var(--color-action-hover);
|
|
--xb-red-50: #fff1f0;
|
|
--xb-red-500: var(--color-market-up);
|
|
--xb-green-50: #ecf9f1;
|
|
--xb-green-500: var(--color-market-down);
|
|
--xb-amber-50: #fff7e8;
|
|
--xb-amber-500: var(--color-warning);
|
|
|
|
--bg: var(--surface-canvas);
|
|
--card: var(--surface-raised);
|
|
--ink: var(--text-primary);
|
|
--sub: var(--text-secondary);
|
|
--faint: var(--text-tertiary);
|
|
--line: var(--border);
|
|
--line-soft: var(--border-subtle);
|
|
--line-strong: var(--border-strong);
|
|
--text: var(--text-primary);
|
|
--text-muted: var(--text-secondary);
|
|
--blue: var(--primary);
|
|
--blue-d: var(--primary-hover);
|
|
--blue-dark: var(--action-hover);
|
|
--blue-soft: var(--color-action-soft);
|
|
--blue-line: var(--color-action-line);
|
|
--up: var(--danger);
|
|
--up-soft: var(--color-market-up-soft);
|
|
--down: var(--success);
|
|
--down-soft: var(--color-market-down-soft);
|
|
--coral: var(--market-up);
|
|
--coral-soft: var(--market-up-soft);
|
|
--green: var(--market-down);
|
|
--green-soft: var(--market-down-soft);
|
|
--amber: var(--color-warning);
|
|
--amber-soft: var(--color-warning-soft);
|
|
--radius: var(--size-radius-lg);
|
|
--shadow: var(--elevation-card);
|
|
--shadow-soft: var(--elevation-soft);
|
|
|
|
--r2-blue: var(--primary);
|
|
--r2-blue-dark: var(--primary-hover);
|
|
--r2-blue-soft: var(--color-action-soft);
|
|
--r2-blue-line: var(--color-action-line);
|
|
--r2-up: var(--danger);
|
|
--r2-up-soft: var(--color-market-up-soft);
|
|
--r2-down: var(--success);
|
|
--r2-down-soft: var(--color-market-down-soft);
|
|
--r2-amber: var(--color-warning);
|
|
--r2-amber-soft: var(--color-warning-soft);
|
|
--r2-ink: var(--text-primary);
|
|
--r2-sub: var(--text-secondary);
|
|
--r2-faint: var(--text-tertiary);
|
|
--r2-line: var(--border);
|
|
--r2-line-soft: var(--border-subtle);
|
|
--r2-bg: var(--surface-canvas);
|
|
--r2-card: var(--surface-raised);
|
|
--r2-radius: var(--size-radius-lg);
|
|
--r2-shadow: var(--elevation-card);
|
|
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Variable", "Segoe UI", "PingFang SC", "Microsoft YaHei UI", sans-serif;
|
|
font-size: 14px;
|
|
}
|
|
|
|
:root[data-theme="dark"] {
|
|
color-scheme: dark;
|
|
--canvas: #121416;
|
|
--surface: #1b1e21;
|
|
--surface-muted: #202428;
|
|
--surface-subtle: #24282d;
|
|
--surface-canvas: var(--canvas);
|
|
--surface-raised: var(--surface);
|
|
--surface-sunken: #16191c;
|
|
--surface-hover: #24282d;
|
|
--surface-selected: #23364a;
|
|
--surface-overlay: #24282d;
|
|
--border: #343a40;
|
|
--border-strong: #474f57;
|
|
--border-subtle: #2a2f34;
|
|
--text-primary: #e8eaed;
|
|
--text-secondary: #adb5bd;
|
|
--text-tertiary: #7f8993;
|
|
--text-inverse: #ffffff;
|
|
--action: #6ca8e8;
|
|
--action-hover: #8bbcf0;
|
|
--action-soft: #23364a;
|
|
--market-up: #f06d73;
|
|
--market-up-soft: #40262a;
|
|
--market-down: #43bc8a;
|
|
--market-down-soft: #1d382f;
|
|
--warning-color: #e2ad58;
|
|
--warning-soft: #3d3220;
|
|
--control-surface: #202428;
|
|
--control-hover: #2a2f34;
|
|
--control-border: #474f57;
|
|
--table-header: #202428;
|
|
--table-hover: #242f39;
|
|
--table-selected: #23364a;
|
|
--focus-ring: rgba(108, 168, 232, .22);
|
|
--backdrop: rgba(0, 0, 0, .66);
|
|
--primary: var(--action);
|
|
--primary-hover: var(--action-hover);
|
|
--danger: var(--market-up);
|
|
--success: var(--market-down);
|
|
--warning: var(--warning-color);
|
|
--card-bg: var(--surface);
|
|
--card-border: var(--border);
|
|
|
|
--xb-gray-25: var(--surface);
|
|
--xb-gray-50: var(--surface-muted);
|
|
--xb-gray-100: var(--canvas);
|
|
--xb-gray-200: var(--border);
|
|
--xb-gray-300: var(--border-strong);
|
|
--xb-gray-500: var(--text-secondary);
|
|
--xb-gray-700: #cbd1d7;
|
|
--xb-gray-900: var(--text-primary);
|
|
--xb-blue-50: var(--action-soft);
|
|
--xb-blue-100: #294866;
|
|
--xb-blue-500: var(--action);
|
|
--xb-blue-600: var(--action-hover);
|
|
--xb-red-50: var(--market-up-soft);
|
|
--xb-red-500: var(--market-up);
|
|
--xb-green-50: var(--market-down-soft);
|
|
--xb-green-500: var(--market-down);
|
|
--xb-amber-50: var(--warning-soft);
|
|
--xb-amber-500: var(--warning-color);
|
|
|
|
--bg: var(--canvas);
|
|
--card: var(--surface);
|
|
--ink: var(--text-primary);
|
|
--sub: var(--text-secondary);
|
|
--faint: var(--text-tertiary);
|
|
--line: var(--border);
|
|
--line-soft: var(--border-subtle);
|
|
--line-strong: var(--border-strong);
|
|
--text: var(--text-primary);
|
|
--text-muted: var(--text-secondary);
|
|
--blue: var(--action);
|
|
--blue-d: var(--action-hover);
|
|
--blue-dark: var(--action-hover);
|
|
--blue-soft: var(--action-soft);
|
|
--blue-line: #42698e;
|
|
--up: var(--market-up);
|
|
--up-soft: var(--market-up-soft);
|
|
--down: var(--market-down);
|
|
--down-soft: var(--market-down-soft);
|
|
--coral: var(--market-up);
|
|
--coral-soft: var(--market-up-soft);
|
|
--green: var(--market-down);
|
|
--green-soft: var(--market-down-soft);
|
|
--amber: var(--warning-color);
|
|
--amber-soft: var(--warning-soft);
|
|
--r2-blue: var(--action);
|
|
--r2-blue-dark: var(--action-hover);
|
|
--r2-blue-soft: var(--action-soft);
|
|
--r2-blue-line: #42698e;
|
|
--r2-up: var(--market-up);
|
|
--r2-up-soft: var(--market-up-soft);
|
|
--r2-down: var(--market-down);
|
|
--r2-down-soft: var(--market-down-soft);
|
|
--r2-amber: var(--warning-color);
|
|
--r2-amber-soft: var(--warning-soft);
|
|
--r2-ink: var(--text-primary);
|
|
--r2-sub: var(--text-secondary);
|
|
--r2-faint: var(--text-tertiary);
|
|
--r2-line: var(--border);
|
|
--r2-line-soft: var(--border-subtle);
|
|
--r2-bg: var(--canvas);
|
|
--r2-card: var(--surface);
|
|
--r2-shadow: var(--shadow-soft);
|
|
|
|
--dialog-ink: var(--text-primary);
|
|
--dialog-line: var(--border);
|
|
--heaven-paper: #191a18;
|
|
--heaven-paper-soft: #20211e;
|
|
--heaven-ink: #e5e0d4;
|
|
--heaven-muted: #aaa497;
|
|
--heaven-rule: #3d3a34;
|
|
--chart-background: #181b1e;
|
|
--chart-grid: #30363c;
|
|
--chart-axis: #a3adb6;
|
|
--chart-zero: #68737d;
|
|
--chart-line: #6ca8e8;
|
|
--chart-average: #e2ad58;
|
|
--chart-up: #f06d73;
|
|
--chart-down: #43bc8a;
|
|
--chart-up-volume: rgba(240, 109, 115, .52);
|
|
--chart-down-volume: rgba(67, 188, 138, .52);
|
|
--chart-area: rgba(108, 168, 232, .12);
|
|
--chart-alert-area: rgba(240, 109, 115, .09);
|
|
--chart-moving-average: #69737d;
|
|
--chart-repair: #e2ad58;
|
|
--chart-ma-10: #d39a45;
|
|
--chart-ma-20: #9aa5af;
|
|
--on-action: #101418;
|
|
--warning-line: #6d5a38;
|
|
--warning-line-strong: #66502d;
|
|
--control-shadow: 0 1px 3px rgba(0, 0, 0, .3);
|
|
--dialog-backdrop: var(--backdrop);
|
|
--ladder-level-1: #2d2426;
|
|
--ladder-level-2: #2b2822;
|
|
--ladder-level-3: #252a2d;
|
|
--ladder-level-4: #20282b;
|
|
--ladder-level-5: #202428;
|
|
--heat-strong-bg: #304f7a;
|
|
--heat-strong-ink: #f2f6fb;
|
|
--heat-warm-bg: #2b405f;
|
|
--heat-warm-ink: #dfeaf7;
|
|
--heat-mild-bg: #293440;
|
|
--heat-mild-ink: #c7d2dc;
|
|
--heaven-field-bg: #23241f;
|
|
--shadow-soft: 0 1px 2px rgba(0, 0, 0, .28), 0 8px 24px rgba(0, 0, 0, .16);
|
|
--shadow: 0 18px 50px rgba(0, 0, 0, .46);
|
|
}
|