mateclaw/mateclaw-ui/src/assets/main.css

876 lines
26 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@import "tailwindcss";
/* ================================================================
CSS Variables — Light / Dark theme
================================================================ */
:root {
/* font system */
--mc-font-body: 'Inter', 'Avenir Next', 'SF Pro Display', 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
--mc-font-mono: 'JetBrains Mono', 'Fira Code', 'SF Mono', Consolas, monospace;
/* type scale */
--mc-text-xs: 11px;
--mc-text-sm: 13px;
--mc-text-base: 15px;
--mc-text-lg: 18px;
--mc-text-xl: 24px;
--mc-text-2xl: 32px;
--mc-leading-tight: 1.25;
--mc-leading-normal: 1.5;
--mc-leading-relaxed: 1.75;
/* radius system */
--mc-radius-sm: 6px;
--mc-radius-md: 12px;
--mc-radius-lg: 16px;
--mc-radius-xl: 20px;
--mc-radius-full: 9999px;
/* brand */
--mc-primary: #d96d46;
--mc-primary-light: #ebb08f;
--mc-primary-hover: #bb4f27;
--mc-primary-bg: #f6e2d7;
--mc-accent: #184a45;
--mc-accent-soft: #dce8e4;
/* surfaces */
--mc-bg: #f6f1ea;
--mc-bg-elevated: #ffffff;
--mc-bg-sunken: #ebe3db;
--mc-bg-muted: #f1e8df;
--mc-surface-strong: #fdfaf6;
--mc-surface-overlay: rgba(255, 255, 255, 0.72);
--mc-panel-top: rgba(255, 255, 255, 0.94);
--mc-panel-bottom: rgba(255, 252, 248, 0.9);
--mc-panel-raised: rgba(255, 255, 255, 0.86);
/* borders */
--mc-border: #d9cec2;
--mc-border-light: #ebe3db;
--mc-border-strong: #cdbdad;
/* text */
--mc-text-primary: #1d1612;
--mc-text-secondary: #665245;
--mc-text-tertiary: #9b7d6c;
--mc-text-inverse: #ffffff;
/* shadows */
--mc-shadow-soft: 0 10px 30px rgba(58, 32, 19, 0.08);
--mc-shadow-medium: 0 18px 48px rgba(58, 32, 19, 0.12);
--mc-shadow-strong: 0 24px 70px rgba(58, 32, 19, 0.16);
--mc-glow: radial-gradient(circle at top, rgba(217, 109, 70, 0.18), transparent 55%);
/* sidebar */
--mc-sidebar-bg: #ffffff;
--mc-sidebar-border: #DDD5CC;
--mc-sidebar-hover: #F5F0EB;
--mc-sidebar-active: #F5E4D8;
--mc-sidebar-text: #6B5344;
--mc-sidebar-text-active: #D97757;
--mc-sidebar-group-title: #A08070;
--mc-sidebar-logo-name: #1C1410;
--mc-sidebar-footer-bg: rgba(245, 238, 230, 0.82);
--mc-sidebar-floating-bg: rgba(255, 252, 248, 0.95);
/* chat */
--mc-chat-bg: #FAFAF8;
--mc-chat-header-bg: #ffffff;
--mc-assistant-bubble-bg: #ffffff;
--mc-assistant-bubble-border: #DDD5CC;
--mc-assistant-bubble-color: #1C1410;
--mc-user-bubble-bg: #D97757;
--mc-user-bubble-color: #ffffff;
--mc-input-bg: #FAFAF8;
--mc-input-border: #DDD5CC;
--mc-input-text: #1C1410;
/* code blocks — light mode: warm beige bg, dark text */
--mc-code-bg: #FAF6F1;
--mc-code-header-bg: #EFE8DE;
--mc-code-header-border: rgba(28, 20, 16, 0.08);
--mc-code-lang-color: #6B5344;
--mc-code-copy-color: #6B5344;
--mc-code-copy-hover-bg: rgba(28, 20, 16, 0.06);
--mc-code-copy-hover-color: #1C1410;
--mc-code-text: #1C1410;
--mc-code-shadow: rgba(0, 0, 0, 0.08);
/* inline code */
--mc-inline-code-bg: rgba(217, 119, 87, 0.1);
--mc-inline-code-color: #7B3F1E;
/* markdown */
--mc-table-header-bg: #F5F0EB;
--mc-table-border: #DDD5CC;
--mc-blockquote-bg: rgba(217, 119, 87, 0.05);
--mc-blockquote-border: #E0B8A0;
--mc-blockquote-color: #6B5344;
--mc-link-color: #C1572B;
--mc-hr-color: #DDD5CC;
/* misc */
--mc-tool-call-bg: #fef9c3;
--mc-tool-call-border: #fde68a;
--mc-tool-call-color: #92400e;
--mc-attachment-bg: #F5E4D8;
--mc-attachment-border: #E0B8A0;
--mc-attachment-color: #7B3F1E;
--mc-thinking-bg: #F5F0EB;
--mc-thinking-text: #5A4030;
--mc-mermaid-bg: #FAFAF8;
--mc-mermaid-border: #DDD5CC;
/* Code block gutter: now theme-aware along with --mc-code-bg.
Light mode = darker gutter on light bg; dark fork below flips it. */
--mc-code-line-number: rgba(28, 20, 16, 0.38);
--mc-thinking-hover: rgba(217, 119, 87, 0.1);
--mc-thinking-icon-bg: rgba(217, 119, 87, 0.12);
--mc-thinking-border: rgba(217, 119, 87, 0.2);
--mc-danger: #C0392B;
--mc-danger-bg: #fee2e2;
--mc-danger-border: #fca5a5;
--mc-danger-hover: #a93226;
--mc-success: #5A8A5A;
--mc-warning: #f59e0b;
--mc-warning-hover: #d97706;
--mc-info: #3b82f6;
/* scrollbar */
--mc-scrollbar-thumb: #C4B5A8;
--mc-scrollbar-thumb-hover: #A08070;
/* workflow canvas — vue-flow surfaces */
--mc-canvas-dot: rgba(0, 0, 0, 0.18);
--mc-edge: #c2b3a5;
--mc-edge-strong: #8a7261;
/* Element Plus light override */
--el-color-primary: #D97757;
--el-font-family: var(--mc-font-body);
color-scheme: light;
}
html.dark {
/* brand (lighter in dark bg context) */
--mc-primary: #eb8f65;
--mc-primary-light: #f1c3ab;
--mc-primary-hover: #d96d46;
--mc-primary-bg: rgba(224, 136, 96, 0.15);
--mc-accent: #5ca69d;
--mc-accent-soft: rgba(92, 166, 157, 0.12);
/* surfaces */
--mc-bg: #17110e;
--mc-bg-elevated: #221a16;
--mc-bg-sunken: #2a211c;
--mc-bg-muted: #201813;
--mc-surface-strong: #2a201a;
--mc-surface-overlay: rgba(34, 26, 22, 0.78);
--mc-panel-top: rgba(36, 28, 24, 0.96);
--mc-panel-bottom: rgba(27, 21, 18, 0.94);
--mc-panel-raised: rgba(42, 32, 26, 0.9);
/* borders */
--mc-border: #3D3028;
--mc-border-light: #2E2420;
--mc-border-strong: #4a392f;
/* text */
--mc-text-primary: #F0EAE4;
--mc-text-secondary: #C4A898;
--mc-text-tertiary: #8A7060;
--mc-text-inverse: #1C1410;
/* shadows */
--mc-shadow-soft: 0 14px 32px rgba(0, 0, 0, 0.22);
--mc-shadow-medium: 0 20px 60px rgba(0, 0, 0, 0.28);
--mc-shadow-strong: 0 28px 90px rgba(0, 0, 0, 0.35);
--mc-glow: radial-gradient(circle at top, rgba(235, 143, 101, 0.12), transparent 55%);
/* sidebar */
--mc-sidebar-bg: #1A1410;
--mc-sidebar-border: #3D3028;
--mc-sidebar-hover: #2E2420;
--mc-sidebar-active: rgba(224, 136, 96, 0.15);
--mc-sidebar-text: #C4A898;
--mc-sidebar-text-active: #E08860;
--mc-sidebar-group-title: #8A7060;
--mc-sidebar-logo-name: #F0EAE4;
--mc-sidebar-footer-bg: rgba(34, 26, 22, 0.9);
--mc-sidebar-floating-bg: rgba(36, 28, 24, 0.96);
/* chat */
--mc-chat-bg: #1A1410;
--mc-chat-header-bg: #231C17;
--mc-assistant-bubble-bg: #231C17;
--mc-assistant-bubble-border: #3D3028;
--mc-assistant-bubble-color: #F0EAE4;
--mc-user-bubble-bg: #D97757;
--mc-user-bubble-color: #ffffff;
--mc-input-bg: #1A1410;
--mc-input-border: #3D3028;
--mc-input-text: #F0EAE4;
/* code blocks — dark mode: deep brown bg, soft text */
--mc-code-bg: #161210;
--mc-code-header-bg: #1E1814;
--mc-code-header-border: rgba(255, 255, 255, 0.06);
--mc-code-lang-color: #8A7060;
--mc-code-copy-color: #8A7060;
--mc-code-copy-hover-bg: rgba(255, 255, 255, 0.08);
--mc-code-copy-hover-color: #F0EAE4;
--mc-code-text: #abb2bf;
--mc-code-shadow: rgba(0, 0, 0, 0.2);
/* inline code */
--mc-inline-code-bg: rgba(224, 136, 96, 0.15);
--mc-inline-code-color: #F0C4A0;
/* markdown */
--mc-table-header-bg: #2E2420;
--mc-table-border: #3D3028;
--mc-blockquote-bg: rgba(224, 136, 96, 0.08);
--mc-blockquote-border: #D97757;
--mc-blockquote-color: #C4A898;
--mc-link-color: #E08860;
--mc-hr-color: #3D3028;
/* misc */
--mc-tool-call-bg: rgba(250, 204, 21, 0.1);
--mc-tool-call-border: rgba(250, 204, 21, 0.2);
--mc-tool-call-color: #fbbf24;
--mc-attachment-bg: rgba(224, 136, 96, 0.12);
--mc-attachment-border: rgba(224, 136, 96, 0.25);
--mc-attachment-color: #F0C4A0;
--mc-thinking-bg: #231C17;
--mc-thinking-text: #C4A898;
--mc-mermaid-bg: #1A1410;
--mc-mermaid-border: #3D3028;
--mc-code-line-number: rgba(138, 112, 96, 0.95);
--mc-thinking-hover: rgba(224, 136, 96, 0.1);
--mc-thinking-icon-bg: rgba(224, 136, 96, 0.12);
--mc-thinking-border: rgba(224, 136, 96, 0.2);
--mc-danger: #E05A4A;
--mc-danger-bg: rgba(224, 90, 74, 0.15);
--mc-danger-border: rgba(224, 90, 74, 0.4);
--mc-danger-hover: #c94a3a;
--mc-success: #7AB87A;
--mc-warning: #fbbf24;
--mc-warning-hover: #f59e0b;
--mc-info: #60a5fa;
/* scrollbar */
--mc-scrollbar-thumb: #5A4438;
--mc-scrollbar-thumb-hover: #7A6050;
/* workflow canvas — darker dots + softer edge color so they read on
the dark background without overpowering the node card. */
--mc-canvas-dot: rgba(255, 255, 255, 0.14);
--mc-edge: #5a4a3e;
--mc-edge-strong: #8c7361;
color-scheme: dark;
}
/* Vue Flow theme bridge — its default stylesheet ships hard-coded
light colors for handles / mini-map / control buttons. Map them to
our theme tokens so dark mode inherits cleanly.
Each selector is bumped to (0,2,0) specificity by scoping to
`.workflow-canvas` because vue-flow's component CSS imports inside
WorkflowCanvas.vue land in the bundle AFTER main.css; equal
specificity would lose. */
.workflow-canvas .vue-flow__handle {
background: var(--mc-edge-strong, #777);
border-color: var(--mc-bg-elevated, #fff);
}
.workflow-canvas .vue-flow__edge-path {
stroke: var(--mc-edge, #999);
}
.workflow-canvas .vue-flow__edge-text {
fill: var(--mc-text-secondary, #555);
font-size: 11px;
}
.workflow-canvas .vue-flow__edge-textbg {
fill: var(--mc-bg-elevated, #fff);
}
.workflow-canvas .vue-flow__background {
background: transparent;
}
.workflow-canvas .vue-flow__minimap {
background: var(--mc-bg-sunken, rgba(0, 0, 0, 0.04));
border: 1px solid var(--mc-border-light, rgba(0, 0, 0, 0.08));
border-radius: 6px;
}
.workflow-canvas .vue-flow__minimap-mask {
fill: var(--mc-bg-muted, rgba(0, 0, 0, 0.06));
stroke: var(--mc-border, transparent);
}
.workflow-canvas .vue-flow__controls {
box-shadow: var(--mc-shadow-soft, 0 2px 6px rgba(0, 0, 0, 0.1));
border-radius: 6px;
overflow: hidden;
background: var(--mc-bg-elevated, #ffffff);
border: 1px solid var(--mc-border-light, rgba(0, 0, 0, 0.08));
}
.workflow-canvas .vue-flow__controls-button {
background: var(--mc-bg-elevated, #ffffff);
border-bottom: 1px solid var(--mc-border-light, rgba(0, 0, 0, 0.08));
fill: var(--mc-text-primary, #333);
color: var(--mc-text-primary, #333);
}
.workflow-canvas .vue-flow__controls-button svg {
fill: currentColor;
}
.workflow-canvas .vue-flow__controls-button:hover {
background: var(--mc-bg-muted, rgba(0, 0, 0, 0.05));
}
/* Round the bottom button so the corner doesn't show the hardcoded grey
border vue-flow ships with. */
.workflow-canvas .vue-flow__controls-button:last-child {
border-bottom: none;
}
/* Selection ring matches the brand accent in both modes. */
.workflow-canvas .vue-flow__node.selected {
box-shadow: 0 0 0 2px var(--mc-primary, #4084ff);
}
/* ================================================================
Base resets
================================================================ */
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body, #app {
min-height: 100%;
}
body {
font-family: var(--mc-font-body);
background-color: var(--mc-bg);
color: var(--mc-text-primary);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-feature-settings: "kern" on;
transition: background-color 0.2s ease, color 0.2s ease;
background-image:
radial-gradient(circle at top left, rgba(217, 109, 70, 0.1), transparent 26%),
radial-gradient(circle at bottom right, rgba(24, 74, 69, 0.08), transparent 24%);
}
html.dark body {
background-image:
radial-gradient(circle at top left, rgba(235, 143, 101, 0.14), transparent 28%),
radial-gradient(circle at bottom right, rgba(92, 166, 157, 0.08), transparent 26%);
}
body::before {
content: '';
position: fixed;
inset: 0;
pointer-events: none;
background-image:
linear-gradient(rgba(255, 255, 255, 0.015) 1px, transparent 1px),
linear-gradient(90deg, rgba(255, 255, 255, 0.015) 1px, transparent 1px);
background-size: 24px 24px;
opacity: 0.35;
mix-blend-mode: soft-light;
}
html.dark body::before {
opacity: 0.18;
mix-blend-mode: normal;
}
::selection {
background: var(--mc-primary-bg);
color: var(--mc-text-primary);
}
/* ================================================================
Scrollbar
================================================================ */
::-webkit-scrollbar { width: 6px; height: 6px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--mc-scrollbar-thumb); border-radius: 3px; }
::-webkit-scrollbar-thumb:hover { background: var(--mc-scrollbar-thumb-hover); }
/* ================================================================
Markdown body (used in non-chat contexts)
================================================================ */
.markdown-body { line-height: 1.75; }
/* headings */
.markdown-body h1,
.markdown-body h2,
.markdown-body h3,
.markdown-body h4,
.markdown-body h5,
.markdown-body h6 {
margin: 20px 0 12px;
font-weight: 600;
line-height: 1.4;
color: var(--mc-text-primary);
}
.markdown-body h1 { font-size: 1.5em; }
.markdown-body h2 { font-size: 1.3em; }
.markdown-body h3 { font-size: 1.15em; }
.markdown-body h4 { font-size: 1em; }
/* inline code */
.markdown-body code {
font-family: var(--mc-font-mono);
font-size: 0.875rem;
}
.markdown-body :not(pre) > code {
background: var(--mc-inline-code-bg);
color: var(--mc-inline-code-color);
padding: 2px 6px;
border-radius: 6px;
font-size: 0.92em;
}
/* pre / code blocks */
.markdown-body pre {
background: var(--mc-code-bg);
border-radius: 12px;
padding: 16px;
overflow-x: auto;
margin: 14px 0;
}
.markdown-body pre code,
.markdown-body pre code.hljs {
background: none !important;
color: var(--mc-code-text);
padding: 0 !important;
border-radius: 0;
font-size: 0.875rem;
display: block;
overflow-x: auto;
line-height: 1.7;
}
/* code-block container (from useMarkdownRenderer)
---------------------------------------------------------------
These rules live globally so they apply consistently to every
markdown-body context (chat bubbles, agent context preview, etc.)
and don't depend on the Vue scope hash. The ! markers on padding
and height defeat the global `.markdown-body pre` rule and any
stray <summary> browser defaults that previously inflated the
header to 400+px tall. */
.markdown-body .code-block {
margin: 14px 0;
border-radius: 12px;
overflow: hidden;
background: var(--mc-code-bg);
border: 1px solid var(--mc-code-header-border);
}
.markdown-body .code-block__header {
display: flex !important;
align-items: center;
justify-content: space-between;
padding: 0 14px !important;
margin: 0 !important;
/* Hard cap — earlier versions (auto / min-height: 0) were being inflated
by the SVG inside the copy button rendering at its UA-default 300×150
when DOMPurify normalised attributes. Fixed height + overflow:hidden
defeats that regardless of child sizing. */
height: 38px !important;
min-height: 38px !important;
max-height: 38px !important;
line-height: 1 !important;
font-size: 12px !important;
background: var(--mc-code-header-bg);
border-bottom: 1px solid var(--mc-code-header-border);
box-sizing: border-box;
overflow: hidden;
}
/* Defence in depth: pin the icon to its declared 14×14 even if the inline
width/height attrs get normalised away. Without this the SVG can default
to 300×150, which is what was inflating the header. */
.markdown-body .code-block__header svg {
width: 14px !important;
height: 14px !important;
flex-shrink: 0;
display: inline-block;
vertical-align: middle;
}
.markdown-body .code-block__header > * {
flex-shrink: 0;
min-width: 0;
}
.markdown-body .code-block__lang {
font-size: 12px;
color: var(--mc-code-lang-color);
font-weight: 500;
letter-spacing: 0.02em;
}
.markdown-body .code-block__lines {
/* Hidden by default — only shown for collapsed details (rule below). */
display: none;
}
.markdown-body .code-block__copy {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 3px 8px;
background: transparent;
border: none;
border-radius: 6px;
color: var(--mc-code-copy-color);
font-size: 12px;
cursor: pointer;
transition: background 0.15s ease, color 0.15s ease;
}
.markdown-body .code-block__copy:hover {
background: var(--mc-code-copy-hover-bg);
color: var(--mc-code-copy-hover-color);
}
/* Kill the GLOBAL .markdown-body pre padding (16px) and margin (14px) — those
are what created the visible "tall header" gap between summary and code. */
.markdown-body .code-block pre {
margin: 0 !important;
padding: 0 !important;
border-radius: 0 !important;
background: transparent !important;
}
.markdown-body .code-block pre code,
.markdown-body .code-block pre code.hljs {
background: transparent !important;
padding: 0 !important;
color: var(--mc-code-text);
display: block;
line-height: 1.55;
}
/* Line-numbered gutter via CSS counter */
.markdown-body .code-block ol.hljs-lines {
counter-reset: ln;
padding: 12px 0;
margin: 0;
list-style: none;
font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
}
.markdown-body .code-block ol.hljs-lines > li {
counter-increment: ln;
display: block;
padding: 0 16px 0 4em;
position: relative;
white-space: pre;
min-height: 1.55em;
line-height: 1.55;
}
.markdown-body .code-block ol.hljs-lines > li::before {
content: counter(ln);
position: absolute;
left: 0;
width: 3em;
text-align: right;
color: var(--mc-code-line-number);
user-select: none;
font-size: 0.85em;
font-variant-numeric: tabular-nums;
}
/* <details>/<summary> reset — strip browser-default marker spacing that
pushed the header sky-high. */
.markdown-body details.code-block--collapsible > summary {
display: block;
list-style: none;
cursor: pointer;
}
.markdown-body details.code-block--collapsible > summary::-webkit-details-marker,
.markdown-body details.code-block--collapsible > summary::marker {
display: none;
content: '';
}
/* Show the line-count badge only when the block is collapsed. */
.markdown-body details.code-block--collapsible:not([open]) .code-block__lines {
display: inline-block;
font-size: 11px;
color: var(--mc-code-lang-color);
margin: 0 12px;
padding: 2px 8px;
border-radius: 4px;
background: var(--mc-code-copy-hover-bg);
user-select: none;
}
.markdown-body details.code-block--collapsible:not([open]) > pre {
display: none;
}
/* ECharts chart block */
.markdown-body .echarts-block {
margin: 14px 0;
border-radius: 12px;
overflow: hidden;
min-height: 350px;
width: 100%;
background: var(--mc-bg-elevated);
border: 1px solid var(--mc-border-light);
}
.markdown-body .echarts-block.echarts-error {
min-height: auto;
padding: 16px;
text-align: center;
color: var(--mc-text-tertiary);
font-size: 13px;
}
/* ================================================================
Shared page shell
================================================================ */
.mc-page-shell {
height: 100%;
overflow-y: auto;
padding: 28px;
}
.mc-page-frame {
position: relative;
border: 1px solid var(--mc-border);
background: var(--mc-surface-overlay);
backdrop-filter: blur(12px) saturate(1.1);
border-radius: 28px;
box-shadow: var(--mc-shadow-soft);
}
/* While a workflow canvas is in fullscreen mode, suppress the backdrop
filter on every page frame. A non-`none` backdrop-filter promotes the
element to a containing block for position:fixed descendants, which
pinned the fullscreen canvas to the frame's top-left instead of the
viewport. The frames sit behind the fullscreen overlay anyway, so
the blur has no visible cost during this transient state. */
body.workflow-canvas-fullscreen .mc-page-frame {
backdrop-filter: none;
}
body.workflow-canvas-fullscreen .mc-page-frame::before {
display: none;
}
.mc-page-frame::before {
content: '';
position: absolute;
inset: 0;
border-radius: inherit;
background: var(--mc-glow);
opacity: 0.8;
pointer-events: none;
}
.mc-page-inner {
position: relative;
z-index: 1;
padding: 28px;
}
.mc-page-header {
display: flex;
align-items: flex-start;
justify-content: space-between;
gap: 18px;
margin-bottom: 28px;
}
.mc-page-kicker {
display: inline-flex;
align-items: center;
gap: 8px;
padding: 6px 10px;
border-radius: 999px;
background: var(--mc-bg-muted);
border: 1px solid var(--mc-border-light);
color: var(--mc-accent);
font-size: 11px;
font-weight: 700;
letter-spacing: 0.08em;
text-transform: uppercase;
margin-bottom: 12px;
}
.mc-page-title {
font-size: clamp(26px, 3vw, 40px);
line-height: 1;
font-weight: 800;
letter-spacing: -0.04em;
color: var(--mc-text-primary);
margin: 0 0 10px;
}
.mc-page-desc {
max-width: 760px;
color: var(--mc-text-secondary);
font-size: 15px;
line-height: 1.7;
}
.mc-surface-card {
border: 1px solid var(--mc-border-light);
background: linear-gradient(180deg, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0.92));
border-radius: var(--mc-radius-xl);
box-shadow: var(--mc-shadow-soft);
transition: box-shadow 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
}
html.dark .mc-surface-card {
background: linear-gradient(180deg, rgba(42, 32, 26, 0.86), rgba(34, 26, 22, 0.96));
}
@media (max-width: 768px) {
.mc-page-shell {
overflow-y: auto !important;
height: auto !important;
min-height: 100%;
}
.mc-page-frame {
overflow: visible !important;
height: auto !important;
min-height: auto;
}
.mc-page-inner {
height: auto !important;
min-height: auto;
}
}
@media (max-width: 900px) {
.mc-page-shell {
padding: 16px;
}
.mc-page-inner {
padding: 18px;
}
.mc-page-frame {
border-radius: 20px;
}
.mc-page-header {
flex-direction: column;
align-items: stretch;
}
.mc-surface-card {
border-radius: 16px;
}
}
@media (max-width: 480px) {
.mc-page-shell {
padding: 8px;
}
.mc-page-inner {
padding: 12px;
}
.mc-page-frame {
border-radius: 14px;
}
.mc-page-title {
font-size: clamp(20px, 5vw, 28px);
}
.mc-surface-card {
border-radius: 12px;
}
.mc-page-header {
gap: 12px;
margin-bottom: 16px;
}
}
/* highlight.js token colors — Atom One Light (works on the warm beige
light-mode code bg). Dark mode swaps to One Dark in the html.dark block
below so colours stay legible against the deep brown #161210. */
.hljs-keyword, .hljs-selector-tag, .hljs-built_in, .hljs-literal { color: #a626a4; }
.hljs-string, .hljs-attr { color: #50a14f; }
.hljs-number { color: #c18401; }
.hljs-comment, .hljs-quote { color: #a0a1a7; font-style: italic; }
.hljs-function .hljs-title, .hljs-title.function_ { color: #4078f2; }
.hljs-type, .hljs-title.class_ { color: #c18401; }
.hljs-variable, .hljs-template-variable { color: #e45649; }
.hljs-tag { color: #e45649; }
.hljs-name { color: #e45649; }
.hljs-attribute { color: #c18401; }
.hljs-symbol, .hljs-bullet { color: #0184bc; }
.hljs-meta { color: #4078f2; }
.hljs-params { color: #383a42; }
.hljs-section { color: #e45649; font-weight: bold; }
.hljs-addition { color: #50a14f; background: rgba(80, 161, 79, 0.1); }
.hljs-deletion { color: #e45649; background: rgba(228, 86, 73, 0.1); }
/* Dark mode: One Dark token palette */
html.dark .hljs-keyword, html.dark .hljs-selector-tag, html.dark .hljs-built_in, html.dark .hljs-literal { color: #c678dd; }
html.dark .hljs-string, html.dark .hljs-attr { color: #98c379; }
html.dark .hljs-number { color: #d19a66; }
html.dark .hljs-comment, html.dark .hljs-quote { color: #5c6370; font-style: italic; }
html.dark .hljs-function .hljs-title, html.dark .hljs-title.function_ { color: #61afef; }
html.dark .hljs-type, html.dark .hljs-title.class_ { color: #e5c07b; }
html.dark .hljs-variable, html.dark .hljs-template-variable { color: #e06c75; }
html.dark .hljs-tag { color: #e06c75; }
html.dark .hljs-name { color: #e06c75; }
html.dark .hljs-attribute { color: #d19a66; }
html.dark .hljs-symbol, html.dark .hljs-bullet { color: #56b6c2; }
html.dark .hljs-meta { color: #61afef; }
html.dark .hljs-params { color: #abb2bf; }
html.dark .hljs-section { color: #e06c75; font-weight: bold; }
html.dark .hljs-addition { color: #98c379; background: rgba(152, 195, 121, 0.1); }
html.dark .hljs-deletion { color: #e06c75; background: rgba(224, 108, 117, 0.1); }
.markdown-body p { margin: 8px 0; }
.markdown-body ul, .markdown-body ol { padding-left: 1.5rem; margin: 8px 0; }
.markdown-body table {
border-collapse: collapse;
/* display:block + overflow-x:auto turns a wide table into its own horizontal
scroll region instead of overflowing the message bubble and getting clipped
by the list's overflow-x:hidden. Narrow tables still stretch to full width. */
display: block;
width: 100%;
max-width: 100%;
overflow-x: auto;
margin: 12px 0;
}
.markdown-body th, .markdown-body td { border: 1px solid var(--mc-table-border); padding: 8px 12px; text-align: left; }
.markdown-body th { background: var(--mc-table-header-bg); font-weight: 600; }
.markdown-body blockquote {
border-left: 4px solid var(--mc-blockquote-border);
margin: 12px 0;
padding: 8px 16px;
color: var(--mc-blockquote-color);
background: var(--mc-blockquote-bg);
border-radius: 0 8px 8px 0;
}
.markdown-body blockquote p { margin: 4px 0; }
.markdown-body hr { border: none; border-top: 1px solid var(--mc-hr-color); margin: 16px 0; }
.markdown-body del { color: var(--mc-text-tertiary); }
.markdown-body a { color: var(--mc-link-color); text-decoration: none; }
.markdown-body a:hover { text-decoration: underline; }
.markdown-body img { max-width: 100%; border-radius: 8px; }
/* ================================================================
Element Plus dark mode override
================================================================ */
html.dark {
--el-bg-color: #231C17;
--el-bg-color-overlay: #2E2420;
--el-bg-color-page: #1A1410;
--el-text-color-primary: #F0EAE4;
--el-text-color-regular: #D0B8A8;
--el-text-color-secondary: #C4A898;
--el-text-color-placeholder: #8A7060;
--el-border-color: #3D3028;
--el-border-color-light: #2E2420;
--el-border-color-lighter: #261E18;
--el-fill-color-blank: #231C17;
--el-fill-color: #2E2420;
--el-fill-color-light: #2A211C;
--el-fill-color-lighter: #231C17;
--el-color-primary: #E08860;
--el-mask-color: rgba(0, 0, 0, 0.6);
}