/* demo-section:dsh-surface:start */
/* Same-document adapter of source.css; generated, do not hand-edit. */
/* Source: packages/client/ui-theme/src/styles/base.css */
/* Base variables referenced by the token sheets and component CSS but defined
 * upstream (deepsuite theme/global.css) — supplied here so the composite
 * --dsw-font-* variables resolve and motion rides the upstream curve. Code
 * font stack deliberately omits a bare `monospace` tail (Windows CJK falls
 * back to SimSun otherwise). */
:host {
  --dsw-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC',
    'Hiragino Sans GB', 'Microsoft YaHei', 'Helvetica Neue', Helvetica, Arial, sans-serif;
  --dsw-font-family-brand: 'Montserrat', var(--dsw-font-family);
  --ds-font-family-code: 'SF Mono', 'JetBrains Mono', 'Fira Code', Consolas,
    'Liberation Mono', Menlo, Courier, 'PingFang SC', 'Microsoft YaHei';
  --ds-ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
  --ds-transition-duration: 0.2s;
  --ds-transition-duration-fast: 0.1s;
  --ds-transition-duration-slow: 0.3s;
  --dsw-radius-xs: 4px;
  --dsw-radius-sm: 8px;
  --dsw-radius-md: 12px;
  --dsw-radius-lg: 16px;
  --dsw-radius-xl: 20px;
  --dsw-radius-panel: 28px;
}

:host {
  --dsw-alias-settings-card-fill: var(--dsw-alias-bg-layer-2);
  --dsw-alias-settings-card-stroke: var(--dsw-alias-border-l4);
}

[data-dsh-automatic-focus]:focus,
[data-dsh-automatic-focus]:focus:focus-visible {
  outline: none;
}


/* Source: packages/client/ui-theme/src/styles/design-platform.css */
/* Figma font-weight 510 (an SF Pro variable-font weight) always renders as
   font-weight: 500 in this UI — non-variable webfonts snap intermediate
   weights unpredictably across platforms. */
:host {
  --dsw-static-amber-100: rgb(254, 245, 231);
  --dsw-static-amber-400: rgb(247, 173, 49);
  --dsw-static-amber-500: rgb(245, 158, 11);
  --dsw-static-amber-600: rgb(221, 134, 41);
  --dsw-static-amber-900: rgb(39, 36, 31);
  --dsw-static-blue-100: rgb(219, 234, 254);
  --dsw-static-blue-300: rgb(147, 197, 253);
  --dsw-static-blue-400: rgb(96, 165, 250);
  --dsw-static-blue-450: rgb(77, 147, 248);
  --dsw-static-blue-500: rgb(59, 130, 246);
  --dsw-static-blue-50: rgb(239, 246, 255);
  --dsw-static-blue-50p: rgb(234, 243, 255);
  --dsw-static-blue-600: rgb(37, 99, 235);
  --dsw-static-blue-75: rgb(229, 240, 255);
  --dsw-static-blue-800: rgb(30, 64, 175);
  --dsw-static-blue-900: rgb(14, 48, 116);
  --dsw-static-blue-950: rgb(23, 37, 84);
  --dsw-static-deepseek-100: rgb(228, 237, 253);
  --dsw-static-deepseek-200: rgb(211, 226, 255);
  --dsw-static-deepseek-300: rgb(183, 200, 254);
  /* Brightened from the platform rgb(103, 158, 254) at the designer's request: legibility on the dark toast surface. */
  --dsw-static-deepseek-400: rgb(122, 170, 255);
  --dsw-static-deepseek-450: rgb(86, 134, 254);
  --dsw-static-deepseek-500: rgb(65, 118, 230);
  --dsw-static-deepseek-550: rgb(21, 94, 255);
  --dsw-static-deepseek-50: rgb(237, 243, 254);
  --dsw-static-deepseek-600: rgb(72, 104, 178);
  --dsw-static-deepseek-700-delete: rgb(47, 76, 143);
  --dsw-static-deepseek-800: rgb(52, 65, 91);
  --dsw-static-deepseek-900: rgb(40, 49, 66);
  --dsw-static-green-100: rgb(230, 250, 237);
  --dsw-static-green-400: rgb(78, 209, 126);
  --dsw-static-green-500: rgb(34, 197, 94);
  --dsw-static-green-500-a08: rgb(34 197 94 / 8%);
  --dsw-static-green-500-a12: rgb(34 197 94 / 12%);
  --dsw-static-green-900: rgb(35, 60, 44);
  --dsw-static-neutral-00: rgb(255, 255, 255);
  --dsw-static-neutral-1000: rgb(0, 0, 0);
  --dsw-static-neutral-100: rgb(245, 245, 245);
  --dsw-static-neutral-150: rgb(237, 237, 237);
  --dsw-static-neutral-200: rgb(229, 229, 229);
  --dsw-static-neutral-250: rgb(220, 220, 220);
  --dsw-static-neutral-300: rgb(212, 212, 212);
  --dsw-static-neutral-400: rgb(162, 164, 166);
  --dsw-static-neutral-500: rgb(127, 130, 135);
  --dsw-static-neutral-50: rgb(250, 250, 250);
  --dsw-static-neutral-550: rgb(101, 103, 107);
  --dsw-static-neutral-600: rgb(84, 85, 87);
  --dsw-static-neutral-700: rgb(60, 60, 61);
  --dsw-static-neutral-800: rgb(41, 41, 41);
  --dsw-static-neutral-850: rgb(33, 33, 35);
  --dsw-static-neutral-900: rgb(15, 15, 15);
  --dsw-static-neutral-bluish-00: rgb(255, 255, 255);
  --dsw-static-neutral-bluish-1000: rgb(15, 17, 21);
  --dsw-static-neutral-bluish-100: rgb(235, 238, 242);
  --dsw-static-neutral-bluish-150: rgb(233, 236, 242);
  --dsw-static-neutral-bluish-200: rgb(225, 229, 238);
  --dsw-static-neutral-bluish-300: rgb(207, 211, 214);
  --dsw-static-neutral-bluish-400: rgb(173, 178, 184);
  --dsw-static-neutral-bluish-500: rgb(151, 157, 166);
  --dsw-static-neutral-bluish-50: rgb(249, 250, 251);
  --dsw-static-neutral-bluish-600: rgb(129, 133, 140);
  --dsw-static-neutral-bluish-60: rgb(245, 246, 247);
  --dsw-static-neutral-bluish-700: rgb(97, 102, 107);
  --dsw-static-neutral-bluish-750: rgb(67, 69, 74);
  --dsw-static-neutral-bluish-75: rgb(241, 243, 245);
  --dsw-static-neutral-bluish-800: rgb(53, 54, 56);
  --dsw-static-neutral-bluish-850: rgb(44, 44, 46);
  --dsw-static-neutral-bluish-875: rgb(35, 35, 36);
  --dsw-static-neutral-bluish-900: rgb(27, 27, 28);
  --dsw-static-neutral-bluish-950: rgb(21, 21, 23);
  --dsw-static-red-100: rgb(254, 226, 226);
  --dsw-static-red-400: rgb(242, 90, 90);
  --dsw-static-red-400-a12: rgb(242 90 90 / 12%);
  --dsw-static-red-500: rgb(239, 68, 68);
  --dsw-static-red-50: rgb(254, 242, 242);
  --dsw-static-red-600: rgb(236, 19, 19);
  --dsw-static-red-600-a08: rgb(236 19 19 / 8%);
  --dsw-static-red-900: rgb(87, 12, 12);
}

:host([data-ds-dark-theme]) {
  --dsw-static-amber-100: rgb(254, 245, 231);
  --dsw-static-amber-400: rgb(247, 173, 49);
  --dsw-static-amber-500: rgb(245, 158, 11);
  --dsw-static-amber-600: rgb(221, 134, 41);
  --dsw-static-amber-900: rgb(39, 36, 31);
  --dsw-static-blue-100: rgb(219, 234, 254);
  --dsw-static-blue-300: rgb(147, 197, 253);
  --dsw-static-blue-400: rgb(96, 165, 250);
  --dsw-static-blue-450: rgb(77, 147, 248);
  --dsw-static-blue-500: rgb(59, 130, 246);
  --dsw-static-blue-50: rgb(239, 246, 255);
  --dsw-static-blue-50p: rgb(234, 243, 255);
  --dsw-static-blue-600: rgb(37, 99, 235);
  --dsw-static-blue-75: rgb(229, 240, 255);
  --dsw-static-blue-800: rgb(30, 64, 175);
  --dsw-static-blue-900: rgb(14, 48, 116);
  --dsw-static-blue-950: rgb(23, 37, 84);
  --dsw-static-deepseek-100: rgb(228, 237, 253);
  --dsw-static-deepseek-200: rgb(211, 226, 255);
  --dsw-static-deepseek-300: rgb(183, 200, 254);
  /* Brightened from the platform rgb(103, 158, 254) at the designer's request: legibility on the dark toast surface. */
  --dsw-static-deepseek-400: rgb(122, 170, 255);
  --dsw-static-deepseek-450: rgb(86, 134, 254);
  --dsw-static-deepseek-500: rgb(65, 118, 230);
  --dsw-static-deepseek-550: rgb(21, 94, 255);
  --dsw-static-deepseek-50: rgb(237, 243, 254);
  --dsw-static-deepseek-600: rgb(72, 104, 178);
  --dsw-static-deepseek-700-delete: rgb(47, 76, 143);
  --dsw-static-deepseek-800: rgb(52, 65, 91);
  --dsw-static-deepseek-900: rgb(40, 49, 66);
  --dsw-static-green-100: rgb(230, 250, 237);
  --dsw-static-green-400: rgb(78, 209, 126);
  --dsw-static-green-500: rgb(34, 197, 94);
  --dsw-static-green-500-a08: rgb(34 197 94 / 8%);
  --dsw-static-green-500-a12: rgb(34 197 94 / 12%);
  --dsw-static-green-900: rgb(35, 60, 44);
  --dsw-static-neutral-00: rgb(255, 255, 255);
  --dsw-static-neutral-1000: rgb(0, 0, 0);
  --dsw-static-neutral-100: rgb(245, 245, 245);
  --dsw-static-neutral-150: rgb(237, 237, 237);
  --dsw-static-neutral-200: rgb(229, 229, 229);
  --dsw-static-neutral-250: rgb(220, 220, 220);
  --dsw-static-neutral-300: rgb(212, 212, 212);
  --dsw-static-neutral-400: rgb(162, 164, 166);
  --dsw-static-neutral-500: rgb(127, 130, 135);
  --dsw-static-neutral-50: rgb(250, 250, 250);
  --dsw-static-neutral-550: rgb(101, 103, 107);
  --dsw-static-neutral-600: rgb(84, 85, 87);
  --dsw-static-neutral-700: rgb(60, 60, 61);
  --dsw-static-neutral-800: rgb(41, 41, 41);
  --dsw-static-neutral-850: rgb(33, 33, 35);
  --dsw-static-neutral-900: rgb(15, 15, 15);
  --dsw-static-neutral-bluish-00: rgb(255, 255, 255);
  --dsw-static-neutral-bluish-1000: rgb(15, 17, 21);
  --dsw-static-neutral-bluish-100: rgb(235, 238, 242);
  --dsw-static-neutral-bluish-150: rgb(233, 236, 242);
  --dsw-static-neutral-bluish-200: rgb(225, 229, 238);
  --dsw-static-neutral-bluish-300: rgb(207, 211, 214);
  --dsw-static-neutral-bluish-400: rgb(173, 178, 184);
  --dsw-static-neutral-bluish-500: rgb(151, 157, 166);
  --dsw-static-neutral-bluish-50: rgb(249, 250, 251);
  --dsw-static-neutral-bluish-600: rgb(129, 133, 140);
  --dsw-static-neutral-bluish-60: rgb(249, 250, 251);
  --dsw-static-neutral-bluish-700: rgb(97, 102, 107);
  --dsw-static-neutral-bluish-750: rgb(67, 69, 74);
  --dsw-static-neutral-bluish-75: rgb(241, 243, 245);
  --dsw-static-neutral-bluish-800: rgb(53, 54, 56);
  --dsw-static-neutral-bluish-850: rgb(44, 44, 46);
  --dsw-static-neutral-bluish-875: rgb(35, 35, 36);
  --dsw-static-neutral-bluish-900: rgb(27, 27, 28);
  --dsw-static-neutral-bluish-950: rgb(21, 21, 23);
  --dsw-static-red-100: rgb(254, 226, 226);
  --dsw-static-red-400: rgb(242, 90, 90);
  --dsw-static-red-400-a12: rgb(242 90 90 / 12%);
  --dsw-static-red-500: rgb(239, 68, 68);
  --dsw-static-red-50: rgb(254, 242, 242);
  --dsw-static-red-600: rgb(236, 19, 19);
  --dsw-static-red-600-a08: rgb(236 19 19 / 8%);
  --dsw-static-red-900: rgb(87, 12, 12);
}

:host {
  --dsw-alias-bg-base: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-bg-document-preview: var(--dsw-static-neutral-bluish-100);
  --dsw-alias-label-document-preview: var(--dsw-static-neutral-bluish-700);
  --dsw-alias-bg-layer-1: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-bg-layer-2: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-bg-layer-3: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-bg-mask-1: rgba(0, 0, 0, 0.24);
  --dsw-alias-bg-mask-2: rgba(0, 0, 0, 0.12);
  --dsw-alias-bg-mask-3: rgba(0, 0, 0, 0.48);
  --dsw-alias-bg-mask-photo: rgba(0, 0, 0, 0.88);
  --dsw-alias-bg-mask-drop: rgba(255, 255, 255, 0.7);
  --dsw-alias-bg-module-platform: var(--dsw-static-neutral-bluish-60);
  --dsw-alias-bg-multi-select: var(--dsw-static-neutral-bluish-60);
  --dsw-alias-bg-overlay: var(--dsw-static-neutral-bluish-150);
  --dsw-alias-bg-skeleton: rgba(0, 0, 0, 0.04);
  --dsw-alias-border-inverted2: rgba(0, 0, 0, 0);
  --dsw-alias-border-inverted: rgba(0, 0, 0, 0);
  --dsw-alias-border-l1: rgba(0, 0, 0, 0.04);
  --dsw-alias-border-l2-darkmode-thin: rgba(0, 0, 0, 0.1);
  --dsw-alias-border-l2: rgba(0, 0, 0, 0.1);
  --dsw-alias-border-l3: rgba(0, 0, 0, 0.12);
  --dsw-alias-border-l4: rgba(0, 0, 0, 0.16);
  --dsw-alias-brand-primary-invert: var(--dsw-static-neutral-bluish-1000);
  --dsw-alias-brand-primary-new-colorprimary-new-color: rgb(65, 118, 230);
  --dsw-alias-brand-primary: var(--dsw-static-neutral-bluish-1000);
  --dsw-alias-brand-text: var(--dsw-static-neutral-bluish-1000);
  --dsw-alias-button-contrast-fill: var(--dsw-static-neutral-bluish-700);
  --dsw-alias-button-elevated-fill: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-button-floating-fill: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-button-floating-hover: var(--dsw-static-neutral-bluish-75);
  --dsw-alias-button-ghost-active-border: var(--dsw-static-neutral-bluish-500);
  --dsw-alias-button-ghost-active-fill: var(--dsw-static-neutral-bluish-100);
  --dsw-alias-button-ghost-active-hover: var(--dsw-static-neutral-bluish-150);
  --dsw-alias-button-info-fill: var(--dsw-static-deepseek-500);
  --dsw-alias-button-info-hover: var(--dsw-static-deepseek-400);
  --dsw-alias-button-primary-dimmed: var(--dsw-static-neutral-bluish-100);
  --dsw-alias-button-primary-fill: var(--dsw-alias-brand-primary);
  --dsw-alias-button-primary-hover: var(--dsw-static-neutral-bluish-750);
  --dsw-alias-button-tool-bar-fill-invisible: rgba(31, 31, 31, 0.36);
  --dsw-alias-button-tool-bar-fill: rgba(84, 85, 87, 0.5);
  --dsw-alias-button-tool-bar-hover: rgba(84, 85, 87, 0.6);
  --dsw-alias-interactive-bg-active: rgba(38, 49, 72, 0.1);
  --dsw-alias-interactive-bg-hover-accent: rgba(38, 49, 72, 0.14);
  --dsw-alias-interactive-bg-hover-danger: rgba(236, 19, 19, 0.05);
  --dsw-alias-interactive-bg-hover-solid: var(--dsw-static-neutral-bluish-75);
  --dsw-alias-interactive-bg-hover: rgba(38, 49, 72, 0.06);
  --dsw-alias-label-caption: var(--dsw-static-neutral-bluish-400);
  --dsw-alias-label-dimmed: var(--dsw-static-neutral-bluish-200);
  --dsw-alias-label-primary-bluish: var(--dsw-static-blue-900);
  --dsw-alias-label-primary-dimmed: var(--dsw-static-neutral-bluish-950);
  --dsw-alias-label-primary-foreground: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-label-primary-inverted: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-label-primary: var(--dsw-static-neutral-bluish-1000);
  --dsw-alias-label-secondary: var(--dsw-static-neutral-bluish-700);
  --dsw-alias-label-tertiary: var(--dsw-static-neutral-bluish-600);
  --dsw-alias-lite-accent: var(--dsw-static-deepseek-550);
  --dsw-alias-lite-accent-foreground: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-menu-icon: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-link: var(--dsw-static-deepseek-500);
  --dsw-alias-markdown-citation: var(--dsw-static-neutral-bluish-100);
  --dsw-alias-markdown-code-block-banner: var(--dsw-static-neutral-bluish-50);
  --dsw-alias-markdown-code-block: var(--dsw-static-neutral-bluish-50);
  --dsw-alias-markdown-code-segment-selected: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-markdown-code-segment-unselected: var(--dsw-static-neutral-bluish-75);
  --dsw-alias-markdown-inline-code: var(--dsw-static-neutral-50);
  --dsw-alias-markdown-placeholder: var(--dsw-static-neutral-bluish-60);
  --dsw-alias-markdown-tag: var(--dsw-static-neutral-bluish-75);
  --dsw-alias-scrollbar-bg-l1: var(--dsw-static-neutral-200);
  --dsw-alias-scrollbar-bg-l2: var(--dsw-static-neutral-200);
  --dsw-alias-scrollbar-hover-l1: var(--dsw-static-neutral-300);
  --dsw-alias-scrollbar-hover-l2: var(--dsw-static-neutral-300);
  --dsw-alias-state-business-primary: var(--dsw-static-deepseek-500);
  --dsw-alias-state-business-tertiary: var(--dsw-static-deepseek-100);
  --dsw-alias-code-diff-added: var(--dsw-static-green-500-a08);
  --dsw-alias-code-diff-deleted: var(--dsw-static-red-600-a08);
  --dsw-alias-file-diff-added-bg: rgb(230, 244, 231);
  --dsw-alias-file-diff-added-gutter: rgb(237, 247, 237);
  --dsw-alias-file-diff-added-marker: rgb(1, 162, 65);
  --dsw-alias-file-diff-deleted-bg: rgb(252, 230, 226);
  --dsw-alias-file-diff-deleted-gutter: rgb(253, 236, 233);
  --dsw-alias-file-diff-deleted-marker: rgb(186, 39, 35);
  --dsw-alias-state-error-primary: var(--dsw-static-red-600);
  --dsw-alias-state-error-secondary: var(--dsw-static-red-400);
  --dsw-alias-state-idle-primary: var(--dsw-static-neutral-300);
  --dsw-alias-state-success-primary: var(--dsw-static-green-500);
  --dsw-alias-state-success-secondary: var(--dsw-static-green-400);
  --dsw-alias-state-success-tertiary: var(--dsw-static-green-100);
  --dsw-alias-state-warn-label: var(--dsw-static-amber-600);
  --dsw-alias-state-warn-primary: var(--dsw-static-amber-500);
  --dsw-alias-state-warn-secondary: var(--dsw-static-amber-400);
  --dsw-alias-state-warn-tertiary: var(--dsw-static-amber-100);
  --dsw-alias-toast-bg: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-toast-label: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-tooltip-bg: var(--dsw-static-neutral-bluish-850);
  --dsw-alias-tooltip-key-bg: color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%);
  --dsw-specific-bubble-highlight: var(--dsw-static-deepseek-200);
  --dsw-specific-bubble: var(--dsw-static-deepseek-50);
  --dsw-specific-input-major: var(--dsw-static-neutral-bluish-00);
  --dsw-specific-login-input: var(--dsw-static-neutral-bluish-50);
  --dsw-menu-surface-fill: rgba(248, 249, 250, 0.58);
  --dsw-specific-menu: var(--dsw-menu-surface-fill);
  --dsw-specific-selector: var(--dsw-static-neutral-bluish-60);
  --dsw-specific-sidebar-fill: var(--dsw-static-neutral-bluish-50);
  --dsw-specific-sidebar-nav-item-active-accent: var(--dsw-static-deepseek-100);
  --dsw-specific-sidebar-nav-item-active: var(--dsw-static-neutral-bluish-100);
  --dsw-specific-sidebar-nav-item-hover: var(--dsw-static-neutral-bluish-75);
  --dsw-specific-tip: var(--dsw-static-neutral-bluish-60);

  background-color: var(--dsw-alias-bg-base);
}

:host([data-ds-dark-theme]) {
  --dsw-alias-bg-base: var(--dsw-static-neutral-bluish-950);
  --dsw-alias-bg-document-preview: var(--dsw-static-neutral-bluish-950);
  --dsw-alias-label-document-preview: var(--dsw-static-neutral-bluish-300);
  --dsw-alias-bg-layer-1: var(--dsw-static-neutral-bluish-875);
  --dsw-alias-bg-layer-2: var(--dsw-static-neutral-bluish-850);
  --dsw-alias-bg-layer-3: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-bg-mask-1: rgba(0, 0, 0, 0.5);
  --dsw-alias-bg-mask-2: rgba(0, 0, 0, 0.2);
  --dsw-alias-bg-mask-3: rgba(0, 0, 0, 0.48);
  --dsw-alias-bg-mask-photo: rgba(0, 0, 0, 0.88);
  --dsw-alias-bg-mask-drop: rgba(39, 39, 48, 0.7);
  --dsw-alias-bg-module-platform: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-bg-multi-select: var(--dsw-static-neutral-850);
  --dsw-alias-bg-overlay: var(--dsw-static-neutral-bluish-700);
  --dsw-alias-bg-skeleton: rgba(255, 255, 255, 0.08);
  --dsw-alias-border-inverted2: rgba(255, 255, 255, 0.08);
  --dsw-alias-border-inverted: rgba(255, 255, 255, 0.06);
  --dsw-alias-border-l1: rgba(255, 255, 255, 0.06);
  --dsw-alias-border-l2-darkmode-thin: rgba(255, 255, 255, 0.06);
  --dsw-alias-border-l2: rgba(255, 255, 255, 0.12);
  --dsw-alias-border-l3: rgba(255, 255, 255, 0.16);
  --dsw-alias-border-l4: rgba(255, 255, 255, 0.2);
  --dsw-alias-brand-primary-invert: var(--dsw-static-neutral-bluish-50);
  --dsw-alias-brand-primary-new-colorprimary-new-color: var(--dsw-static-deepseek-450);
  --dsw-alias-brand-primary: var(--dsw-static-neutral-bluish-50);
  --dsw-alias-brand-text: var(--dsw-static-neutral-bluish-50);
  --dsw-alias-button-contrast-fill: var(--dsw-static-neutral-bluish-50);
  --dsw-alias-button-elevated-fill: var(--dsw-static-neutral-bluish-750);
  --dsw-alias-button-floating-fill: var(--dsw-static-neutral-bluish-850);
  --dsw-alias-button-floating-hover: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-button-ghost-active-border: var(--dsw-static-neutral-bluish-600);
  --dsw-alias-button-ghost-active-fill: var(--dsw-static-neutral-bluish-750);
  --dsw-alias-button-ghost-active-hover: var(--dsw-static-neutral-bluish-700);
  --dsw-alias-button-info-fill: var(--dsw-static-deepseek-400);
  --dsw-alias-button-info-hover: var(--dsw-static-deepseek-500);
  --dsw-alias-button-primary-dimmed: var(--dsw-static-neutral-bluish-750);
  --dsw-alias-button-primary-fill: var(--dsw-alias-brand-primary);
  --dsw-alias-button-primary-hover: var(--dsw-static-neutral-bluish-100);
  --dsw-alias-button-tool-bar-fill-invisible: rgba(31, 31, 31, 0.36);
  --dsw-alias-button-tool-bar-fill: rgba(84, 85, 87, 0.5);
  --dsw-alias-button-tool-bar-hover: rgba(84, 85, 87, 0.6);
  --dsw-alias-interactive-bg-active: rgba(255, 255, 255, 0.14);
  --dsw-alias-interactive-bg-hover-accent: rgba(255, 255, 255, 0.24);
  --dsw-alias-interactive-bg-hover-danger: rgba(242, 90, 90, 0.15);
  --dsw-alias-interactive-bg-hover-solid: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-interactive-bg-hover: rgba(255, 255, 255, 0.08);
  --dsw-alias-label-caption: var(--dsw-static-neutral-bluish-600);
  --dsw-alias-label-dimmed: var(--dsw-static-neutral-bluish-750);
  --dsw-alias-label-primary-bluish: var(--dsw-static-neutral-bluish-50);
  --dsw-alias-label-primary-dimmed: var(--dsw-static-neutral-bluish-100);
  --dsw-alias-label-primary-foreground: var(--dsw-static-neutral-bluish-1000);
  --dsw-alias-label-primary-inverted: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-label-primary: var(--dsw-static-neutral-bluish-50);
  --dsw-alias-label-secondary: var(--dsw-static-neutral-bluish-300);
  --dsw-alias-label-tertiary: var(--dsw-static-neutral-bluish-400);
  --dsw-alias-lite-accent: var(--dsw-static-deepseek-550);
  --dsw-alias-lite-accent-foreground: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-menu-icon: var(--dsw-alias-label-primary-dimmed);
  --dsw-alias-link: var(--dsw-static-deepseek-400);
  --dsw-alias-markdown-citation: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-markdown-code-block-banner: var(--dsw-static-neutral-bluish-850);
  --dsw-alias-markdown-code-block: var(--dsw-static-neutral-bluish-900);
  --dsw-alias-markdown-code-segment-selected: var(--dsw-static-neutral-bluish-800);
  --dsw-alias-markdown-code-segment-unselected: var(--dsw-static-neutral-bluish-900);
  --dsw-alias-markdown-inline-code: var(--dsw-static-neutral-800);
  --dsw-alias-markdown-placeholder: var(--dsw-static-neutral-bluish-850);
  --dsw-alias-markdown-tag: var(--dsw-static-neutral-bluish-850);
  --dsw-alias-scrollbar-bg-l1: var(--dsw-static-neutral-700);
  --dsw-alias-scrollbar-bg-l2: var(--dsw-static-neutral-600);
  --dsw-alias-scrollbar-hover-l1: var(--dsw-static-neutral-600);
  --dsw-alias-scrollbar-hover-l2: var(--dsw-static-neutral-550);
  --dsw-alias-state-business-primary: var(--dsw-static-deepseek-400);
  --dsw-alias-state-business-tertiary: var(--dsw-static-deepseek-800);
  --dsw-alias-code-diff-added: var(--dsw-static-green-500-a12);
  --dsw-alias-code-diff-deleted: var(--dsw-static-red-400-a12);
  --dsw-alias-file-diff-added-bg: rgb(31, 49, 36);
  --dsw-alias-file-diff-added-gutter: rgb(19, 32, 22);
  --dsw-alias-file-diff-added-marker: rgb(65, 201, 119);
  --dsw-alias-file-diff-deleted-bg: rgb(60, 31, 27);
  --dsw-alias-file-diff-deleted-gutter: rgb(40, 19, 14);
  --dsw-alias-file-diff-deleted-marker: rgb(250, 66, 62);
  --dsw-alias-state-error-primary: var(--dsw-static-red-400);
  --dsw-alias-state-error-secondary: var(--dsw-static-red-400);
  --dsw-alias-state-idle-primary: var(--dsw-static-neutral-600);
  --dsw-alias-state-success-primary: var(--dsw-static-green-500);
  --dsw-alias-state-success-secondary: var(--dsw-static-green-400);
  --dsw-alias-state-success-tertiary: var(--dsw-static-green-900);
  --dsw-alias-state-warn-label: var(--dsw-static-amber-600);
  --dsw-alias-state-warn-primary: var(--dsw-static-amber-500);
  --dsw-alias-state-warn-secondary: var(--dsw-static-amber-400);
  --dsw-alias-state-warn-tertiary: var(--dsw-static-amber-900);
  --dsw-alias-toast-bg: var(--dsw-static-neutral-bluish-750);
  --dsw-alias-toast-label: var(--dsw-static-neutral-bluish-00);
  --dsw-alias-tooltip-bg: var(--dsw-static-neutral-bluish-750);
  --dsw-alias-tooltip-key-bg: color-mix(in srgb, var(--dsw-alias-tooltip-bg), white 18%);
  --dsw-specific-bubble-highlight: var(--dsw-static-neutral-bluish-750);
  --dsw-specific-bubble: var(--dsw-static-neutral-bluish-850);
  --dsw-specific-input-major: var(--dsw-static-neutral-bluish-850);
  --dsw-specific-login-input: var(--dsw-static-neutral-bluish-900);
  --dsw-menu-surface-fill: rgba(67, 69, 74, 0.45);
  --dsw-specific-menu: var(--dsw-menu-surface-fill);
  --dsw-specific-selector: var(--dsw-static-neutral-bluish-800);
  --dsw-specific-sidebar-fill: var(--dsw-static-neutral-bluish-900);
  --dsw-specific-sidebar-nav-item-active-accent: var(--dsw-static-neutral-bluish-800);
  --dsw-specific-sidebar-nav-item-active: var(--dsw-static-neutral-bluish-750);
  --dsw-specific-sidebar-nav-item-hover: var(--dsw-static-neutral-bluish-850);
  --dsw-specific-tip: var(--dsw-static-neutral-bluish-800);
}

/* Overlays without MenuSurface's opaque backing cannot blur page content over
 * native vibrancy reliably, so their fill stays nearly opaque on macOS. */
:host([data-platform='darwin']) {
  --dsw-specific-menu: rgba(248, 249, 250, 0.94);
}

:host([data-platform='darwin'][data-ds-dark-theme]) {
  --dsw-specific-menu: rgba(48, 49, 54, 0.94);
}


/* Source: packages/client/ui-theme/src/styles/gradient-shadow-text.css */
:host {
  --dsw-linear-gradient-think: linear-gradient(180deg, #fff 20.19%, rgba(255, 255, 255, 0) 100%);
  --dsw-linear-think-select: linear-gradient(180deg, #f5f6f7 20.19%, rgba(245, 246, 247, 0) 100%);
  /* 阴影 */
  --dsw-shadow-lv1: 0 2px 4px 0 rgba(0, 0, 0, 0.05);
  --dsw-shadow-lv1-blur: 0 4px 12px 0 rgba(0, 0, 0, 0.02);
  --dsw-shadow-lv2: 0 4px 12px 0 rgba(0, 0, 0, 0.02), 0 2px 8px 0 rgba(0, 0, 0, 0.04);
  --dsw-shadow-lv3:
    0 0 1px 0 rgba(0, 0, 0, 0.2), 0 0 4px 0 rgba(0, 0, 0, 0.02), 0 12px 32px 0 rgba(0, 0, 0, 0.08);
  /* Elevation：浮层/面板/面型按钮的描边+投影三件套。0.5px 发丝描边画在
     box-shadow 里（组件配 border: 0，不占布局），叠两层极淡柔光；深色主题下
     柔光几乎不可见，由描边承担分离。描边颜色经 --dsw-elevation-stroke-color
     间接，组件可重绑（菜单面重绑最浅的 l1、输入框重绑 l2，输入框的
     workspace-trigger 态置 transparent 只保留柔光）。soft 供输入框：更大
     模糊、更低透明度的柔光。默认色只声明在 body 上，让表面的重绑沿继承
     传给真正消费投影的后代。 */
  --dsw-elevation-stroke-color: var(--dsw-alias-border-l4);
  /* Blocking masks dim the page; menu backgrounds retain their blur. */
  --dsw-mask-blur: none;
  --dsw-menu-backdrop-filter: blur(40px) saturate(150%);
}

:host([data-ds-dark-theme]) [data-menu-material] {
  --dsw-elevation-stroke-color: var(--dsw-alias-border-l3);
}

/* 派生 elevation 值逐元素声明而非从 body 继承：继承传下来的是在 body 上就
   已替换完 var() 的值，组件重绑 --dsw-elevation-stroke-color 将无法进入
   var(--dsw-elevation-*)；逐元素声明让每个元素按自己看到的描边色重新替换
   （同 scrollbar.css 对 --dsh-scrollbar-thumb 的处理）。 */
:host,
:host * {
  --dsw-elevation-stroke: 0 0 0 0.5px var(--dsw-elevation-stroke-color);
  --dsw-elevation-panel:
    var(--dsw-elevation-stroke), 0 3px 8px 0 rgba(0, 0, 0, 0.03), 0 0 16px 0 rgba(0, 0, 0, 0.02);
  --dsw-elevation-prominent:
    var(--dsw-elevation-stroke), 0 3px 8px 0 rgba(0, 0, 0, 0.04), 0 0 20px 0 rgba(0, 0, 0, 0.05);
  --dsw-elevation-soft:
    var(--dsw-elevation-stroke), 0 4px 16px 0 rgba(0, 0, 0, 0.03), 0 0 24px 0 rgba(0, 0, 0, 0.03);
}

:host([data-ds-dark-theme]) {
  --dsw-linear-gradient-think: linear-gradient(180deg, #151517 20.19%, rgba(21, 21, 23, 0) 100%);
  --dsw-linear-think-select: linear-gradient(180deg, #232325 20.19%, rgba(35, 35, 37, 0) 100%);
}

/* ---------- 字体 ---------- */
/* 由 @deepseek-figma-plugin/custom-variable-name 插件导出 */
/* Markdown 阶梯整体按 0.875（正文 16 → 14）等比缩放，四舍五入到整数像素；
   重新从 Figma 导出时需要保留这一缩放。 */
/* 正文字号调节：--dsh-content-font-size 由主题 bootstrap 与 ThemePresenter
   写在 body 上（整数 px，12–17，默认 14）。标题与正文变体按同一像素增量
   （--dsh-content-font-delta）随动，保持层级。低一档文本（think、工具/bash
   行的标题与摘要、markdown 表格、流内次级说明等）统一读
   --dsh-content-font-size-secondary：设置 ≤14 时为设置值 −1，>14 时为
   设置值 −2（12→11、13→12、14→13、15→13、16→14、17→15）。式中
   max(13px,·) 的作用是让低设置取 −1 而非 −2，不是结果下限——12 设置下
   层级触底 11px。small、code 属于密集次级文本，保持固定。 */
:host {
  --dsh-content-font-delta: calc(var(--dsh-content-font-size, 14px) - 14px);
  --dsh-content-font-size-secondary: min(calc(var(--dsh-content-font-size, 14px) - 1px), max(13px, calc(var(--dsh-content-font-size, 14px) - 2px)));
  --dsh-content-font-delta-secondary: calc(var(--dsh-content-font-size-secondary) - 13px);

  --dsw-font-markdown-h1: 700 calc(21px + var(--dsh-content-font-delta)) / calc(30px + var(--dsh-content-font-delta)) var(--dsw-font-family);
  --dsw-font-markdown-h1-font-family: var(--dsw-font-family);
  --dsw-font-markdown-h1-font-weight: 700;
  --dsw-font-markdown-h1-line-height: calc(30px + var(--dsh-content-font-delta));
  --dsw-font-markdown-h1-font-size: calc(21px + var(--dsh-content-font-delta));
  --dsw-font-markdown-h1-font-style: normal;

  --dsw-font-markdown-h2: 700 calc(19px + var(--dsh-content-font-delta)) / calc(28px + var(--dsh-content-font-delta)) var(--dsw-font-family);
  --dsw-font-markdown-h2-font-family: var(--dsw-font-family);
  --dsw-font-markdown-h2-font-weight: 700;
  --dsw-font-markdown-h2-line-height: calc(28px + var(--dsh-content-font-delta));
  --dsw-font-markdown-h2-font-size: calc(19px + var(--dsh-content-font-delta));
  --dsw-font-markdown-h2-font-style: normal;

  --dsw-font-markdown-h3: 700 calc(18px + var(--dsh-content-font-delta)) / calc(26px + var(--dsh-content-font-delta)) var(--dsw-font-family);
  --dsw-font-markdown-h3-font-family: var(--dsw-font-family);
  --dsw-font-markdown-h3-font-weight: 700;
  --dsw-font-markdown-h3-line-height: calc(26px + var(--dsh-content-font-delta));
  --dsw-font-markdown-h3-font-size: calc(18px + var(--dsh-content-font-delta));
  --dsw-font-markdown-h3-font-style: normal;

  --dsw-font-markdown-h4: 600 var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);
  --dsw-font-markdown-h4-font-family: var(--dsw-font-family);
  --dsw-font-markdown-h4-font-weight: 600;
  --dsw-font-markdown-h4-line-height: calc(24px + var(--dsh-content-font-delta));
  --dsw-font-markdown-h4-font-size: var(--dsh-content-font-size, 14px);
  --dsw-font-markdown-h4-font-style: normal;

  --dsw-font-markdown-base: var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);
  --dsw-font-markdown-base-font-family: var(--dsw-font-family);
  --dsw-font-markdown-base-font-weight: 400;
  --dsw-font-markdown-base-line-height: calc(24px + var(--dsh-content-font-delta));
  --dsw-font-markdown-base-font-size: var(--dsh-content-font-size, 14px);
  --dsw-font-markdown-base-font-style: normal;

  --dsw-font-markdown-base-strong: 600 var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);
  --dsw-font-markdown-base-strong-font-family: var(--dsw-font-family);
  --dsw-font-markdown-base-strong-font-weight: 600;
  --dsw-font-markdown-base-strong-line-height: calc(24px + var(--dsh-content-font-delta));
  --dsw-font-markdown-base-strong-font-size: var(--dsh-content-font-size, 14px);
  --dsw-font-markdown-base-strong-font-style: normal;

  --dsw-font-markdown-base-italic: italic var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);
  --dsw-font-markdown-base-italic-font-family: var(--dsw-font-family);
  --dsw-font-markdown-base-italic-font-weight: 400;
  --dsw-font-markdown-base-italic-line-height: calc(24px + var(--dsh-content-font-delta));
  --dsw-font-markdown-base-italic-font-size: var(--dsh-content-font-size, 14px);
  --dsw-font-markdown-base-italic-font-style: italic;

  --dsw-font-markdown-base-strong-italic: italic 600 var(--dsh-content-font-size, 14px) / calc(24px + var(--dsh-content-font-delta)) var(--dsw-font-family);
  --dsw-font-markdown-base-strong-italic-font-family: var(--dsw-font-family);
  --dsw-font-markdown-base-strong-italic-font-weight: 600;
  --dsw-font-markdown-base-strong-italic-line-height: calc(24px + var(--dsh-content-font-delta));
  --dsw-font-markdown-base-strong-italic-font-size: var(--dsh-content-font-size, 14px);
  --dsw-font-markdown-base-strong-italic-font-style: italic;

  --dsw-font-markdown-table: var(--dsh-content-font-size-secondary, 13px)/calc(22px + var(--dsh-content-font-delta-secondary, 0px)) var(--dsw-font-family);
  --dsw-font-markdown-table-font-family: var(--dsw-font-family);
  --dsw-font-markdown-table-font-weight: 400;
  --dsw-font-markdown-table-line-height: calc(22px + var(--dsh-content-font-delta-secondary, 0px));
  --dsw-font-markdown-table-font-size: var(--dsh-content-font-size-secondary, 13px);
  --dsw-font-markdown-table-font-style: normal;

  --dsw-font-markdown-table-head: 500 var(--dsh-content-font-size-secondary, 13px)/calc(22px + var(--dsh-content-font-delta-secondary, 0px)) var(--dsw-font-family);
  --dsw-font-markdown-table-head-font-family: var(--dsw-font-family);
  --dsw-font-markdown-table-head-font-weight: 500;
  --dsw-font-markdown-table-head-line-height: calc(22px + var(--dsh-content-font-delta-secondary, 0px));
  --dsw-font-markdown-table-head-font-size: var(--dsh-content-font-size-secondary, 13px);
  --dsw-font-markdown-table-head-font-style: normal;

  --dsw-font-markdown-small: 12px/20px var(--dsw-font-family);
  --dsw-font-markdown-small-font-family: var(--dsw-font-family);
  --dsw-font-markdown-small-font-weight: 400;
  --dsw-font-markdown-small-line-height: 20px;
  --dsw-font-markdown-small-font-size: 12px;
  --dsw-font-markdown-small-font-style: normal;

  --dsw-font-markdown-small-strong: 600 12px/20px var(--dsw-font-family);
  --dsw-font-markdown-small-strong-font-family: var(--dsw-font-family);
  --dsw-font-markdown-small-strong-font-weight: 600;
  --dsw-font-markdown-small-strong-line-height: 20px;
  --dsw-font-markdown-small-strong-font-size: 12px;
  --dsw-font-markdown-small-strong-font-style: normal;

  --dsw-font-markdown-small-italic: italic 12px/20px var(--dsw-font-family);
  --dsw-font-markdown-small-italic-font-family: var(--dsw-font-family);
  --dsw-font-markdown-small-italic-font-weight: 400;
  --dsw-font-markdown-small-italic-line-height: 20px;
  --dsw-font-markdown-small-italic-font-size: 12px;
  --dsw-font-markdown-small-italic-font-style: italic;

  --dsw-font-markdown-small-strong-italic: italic 600 12px/20px var(--dsw-font-family);
  --dsw-font-markdown-small-strong-italic-font-family: var(--dsw-font-family);
  --dsw-font-markdown-small-strong-italic-font-weight: 600;
  --dsw-font-markdown-small-strong-italic-line-height: 20px;
  --dsw-font-markdown-small-strong-italic-font-size: 12px;
  --dsw-font-markdown-small-strong-italic-font-style: italic;

  --dsw-font-markdown-code: 12px/19px var(--ds-font-family-code);
  --dsw-font-markdown-code-font-family: var(--ds-font-family-code);
  --dsw-font-markdown-code-font-weight: 400;
  --dsw-font-markdown-code-line-height: 19px;
  --dsw-font-markdown-code-font-size: 12px;
  --dsw-font-markdown-code-font-style: normal;

  --dsw-font-markdown-code-block: 11px/19px var(--ds-font-family-code);
  --dsw-font-markdown-code-block-font-family: var(--ds-font-family-code);
  --dsw-font-markdown-code-block-font-weight: 400;
  --dsw-font-markdown-code-block-line-height: 19px;
  --dsw-font-markdown-code-block-font-size: 11px;
  --dsw-font-markdown-code-block-font-style: normal;

  /* 手工补充（非插件导出）：tool row 展开卡片内的小号 code 字体。 */
  --dsw-font-markdown-code-block-small: 11px/16px var(--ds-font-family-code);
  --dsw-font-markdown-code-block-small-font-family: var(--ds-font-family-code);
  --dsw-font-markdown-code-block-small-font-weight: 400;
  --dsw-font-markdown-code-block-small-line-height: 16px;
  --dsw-font-markdown-code-block-small-font-size: 11px;
  --dsw-font-markdown-code-block-small-font-style: normal;

  --dsw-font-xl-24: 600 24px/32px var(--dsw-font-family);
  --dsw-font-xl-24-font-family: var(--dsw-font-family);
  --dsw-font-xl-24-font-weight: 600;
  --dsw-font-xl-24-line-height: 32px;
  --dsw-font-xl-24-font-size: 24px;
  --dsw-font-xl-24-font-style: normal;

  --dsw-font-l-20: 500 20px/28px var(--dsw-font-family);
  --dsw-font-l-20-font-family: var(--dsw-font-family);
  --dsw-font-l-20-font-weight: 500;
  --dsw-font-l-20-line-height: 28px;
  --dsw-font-l-20-font-size: 20px;
  --dsw-font-l-20-font-style: normal;

  --dsw-font-m-18: 500 16px/28px var(--dsw-font-family);
  --dsw-font-m-18-font-family: var(--dsw-font-family);
  --dsw-font-m-18-font-weight: 500;
  --dsw-font-m-18-line-height: 28px;
  --dsw-font-m-18-font-size: 16px;
  --dsw-font-m-18-font-style: normal;

  --dsw-font-base-16: 16px/24px var(--dsw-font-family);
  --dsw-font-base-16-font-family: var(--dsw-font-family);
  --dsw-font-base-16-font-weight: 400;
  --dsw-font-base-16-line-height: 24px;
  --dsw-font-base-16-font-size: 16px;
  --dsw-font-base-16-font-style: normal;

  --dsw-font-base-strong-16: 500 16px/24px var(--dsw-font-family);
  --dsw-font-base-strong-16-font-family: var(--dsw-font-family);
  --dsw-font-base-strong-16-font-weight: 500;
  --dsw-font-base-strong-16-line-height: 24px;
  --dsw-font-base-strong-16-font-size: 16px;
  --dsw-font-base-strong-16-font-style: normal;

  --dsw-font-s-14: 14px/22px var(--dsw-font-family);
  --dsw-font-s-14-font-family: var(--dsw-font-family);
  --dsw-font-s-14-font-weight: 400;
  --dsw-font-s-14-line-height: 22px;
  --dsw-font-s-14-font-size: 14px;
  --dsw-font-s-14-font-style: normal;

  --dsw-font-s-strong-14: 500 14px/22px var(--dsw-font-family);
  --dsw-font-s-strong-14-font-family: var(--dsw-font-family);
  --dsw-font-s-strong-14-font-weight: 500;
  --dsw-font-s-strong-14-line-height: 22px;
  --dsw-font-s-strong-14-font-size: 14px;
  --dsw-font-s-strong-14-font-style: normal;

  --dsw-font-xs-13: 13px/20px var(--dsw-font-family);
  --dsw-font-xs-13-font-family: var(--dsw-font-family);
  --dsw-font-xs-13-font-weight: 400;
  --dsw-font-xs-13-line-height: 20px;
  --dsw-font-xs-13-font-size: 13px;
  --dsw-font-xs-13-font-style: normal;

  --dsw-font-xs-strong-13: 500 13px/20px var(--dsw-font-family);
  --dsw-font-xs-strong-13-font-family: var(--dsw-font-family);
  --dsw-font-xs-strong-13-font-weight: 500;
  --dsw-font-xs-strong-13-line-height: 20px;
  --dsw-font-xs-strong-13-font-size: 13px;
  --dsw-font-xs-strong-13-font-style: normal;

  --dsw-font-xxs-12: 12px/18px var(--dsw-font-family);
  --dsw-font-xxs-12-font-family: var(--dsw-font-family);
  --dsw-font-xxs-12-font-weight: 400;
  --dsw-font-xxs-12-line-height: 18px;
  --dsw-font-xxs-12-font-size: 12px;
  --dsw-font-xxs-12-font-style: normal;

  --dsw-font-xxs-strong-12: 500 12px/18px var(--dsw-font-family);
  --dsw-font-xxs-strong-12-font-family: var(--dsw-font-family);
  --dsw-font-xxs-strong-12-font-weight: 500;
  --dsw-font-xxs-strong-12-line-height: 18px;
  --dsw-font-xxs-strong-12-font-size: 12px;
  --dsw-font-xxs-strong-12-font-style: normal;

  --dsw-font-xxxs-11: 11px/14px var(--dsw-font-family);
  --dsw-font-xxxs-11-font-family: var(--dsw-font-family);
  --dsw-font-xxxs-11-font-weight: 400;
  --dsw-font-xxxs-11-line-height: 14px;
  --dsw-font-xxxs-11-font-size: 11px;
  --dsw-font-xxxs-11-font-style: normal;

  --dsw-font-xxxs-strong-11: 500 11px/14px var(--dsw-font-family);
  --dsw-font-xxxs-strong-11-font-family: var(--dsw-font-family);
  --dsw-font-xxxs-strong-11-font-weight: 500;
  --dsw-font-xxxs-strong-11-line-height: 14px;
  --dsw-font-xxxs-strong-11-font-size: 11px;
  --dsw-font-xxxs-strong-11-font-style: normal;
}


/* Source: packages/client/ui-theme/src/styles/scrollbar.css */
/* Scrollbar skin: the sole consumer of the four --dsw-alias-scrollbar-*
 * tokens. Without it every scrolling region renders the UA scrollbar, which
 * ignores the theme — a light native bar over the dark palette.
 *
 * The rules sit on `body`, not `html`: design-platform.css declares the
 * --dsw-alias-* tokens on `body` (and the dark overrides on
 * `body[data-ds-dark-theme]`), and custom properties only inherit downward,
 * so an `html` rule resolves them to the guaranteed-invalid value and
 * `scrollbar-color` falls back to `auto`.
 *
 * Surfaces pick their elevation by rebinding --dsh-scrollbar-thumb{,-hover}:
 * the l1 pair here is the base-surface default, and an elevated surface
 * (menu, popover, dialog) rebinds to the l2 pair on its own container. A
 * scroll container may also rebind the three geometry variables below. */

:host {
  --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l1);
  --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l1);
  --dsh-scrollbar-thumb-border: 0px;
  --dsh-scrollbar-track-margin: 0px;
  /* The WebKit bar's layout width, mirrored by the ::-webkit-scrollbar rule
     below. A surface that must align itself beside a space-consuming bar
     (ConversationRoot's overlay composer seat) reads this instead of
     hardcoding the number. */
  --dsh-scrollbar-width: 5px;
}

/* The two paths are mutually exclusive, and the gate is load-bearing rather
   than defensive. A non-`auto` `scrollbar-width` or `scrollbar-color` makes
   Chromium and Safari drop every `::-webkit-scrollbar*` rule for that
   element, including `::-webkit-scrollbar-thumb:hover` — measured in chromium
   as a `::-webkit-scrollbar` width taking effect on its own and being
   ignored as soon as `scrollbar-width: thin` is added. Declaring both
   unconditionally therefore leaves the hover tokens with no rendering at all,
   because the engines that implement the hover pseudo-element are exactly the
   ones the standard properties silence, and Firefox has no hover
   pseudo-element to fall back on.

   `not selector(::-webkit-scrollbar)` is true only where the pseudo-element
   is unimplemented, so Firefox takes the standard path and WebKit-based
   engines take the pseudo-element path. An engine too old for the
   `selector()` function makes the condition invalid, which evaluates false
   and selects the pseudo-element path — the correct side for the pre-16.4
   Safari that is the realistic case. */
@supports not selector(::-webkit-scrollbar) {
  /* Declared on every element rather than inherited from `body`. Inheriting
     would pass down the COLOUR already substituted at `body`, so a descendant
     rebinding --dsh-scrollbar-thumb could not change it; re-declaring makes
     each element substitute the variable as it sees it, which is what gives
     an elevated surface a working rebind. `scrollbar-width` is not an
     inherited property at all, so it needs the per-element declaration
     regardless.

     No hover counterpart exists on this path: `scrollbar-color` states one
     thumb colour and the engine derives its own hover treatment. */
  :host,
  :host * {
    scrollbar-width: thin;
    scrollbar-color: var(--dsh-scrollbar-thumb) transparent;
  }
}

/* Not gated in turn: an engine that does not implement these pseudo-elements
   drops the rules as unknown selectors, so the gate would only restate what
   selector matching already does. Not inherited either, hence the unscoped
   selectors. */
::-webkit-scrollbar {
  width: var(--dsh-scrollbar-width);
  height: var(--dsh-scrollbar-width);
}

/* Track stays transparent so the thumb reads against whatever surface scrolls
   under it; only the thumb carries a token colour. */
::-webkit-scrollbar-track {
  margin-block: var(--dsh-scrollbar-track-margin);
  background: transparent;
}

::-webkit-scrollbar-thumb {
  border: var(--dsh-scrollbar-thumb-border) solid transparent;
  border-radius: 999px;
  corner-shape: round;
  background: var(--dsh-scrollbar-thumb);
  background-clip: content-box;
}

::-webkit-scrollbar-thumb:hover {
  background-color: var(--dsh-scrollbar-thumb-hover);
}

/* Both scrollbars meeting in a corner: no separate token, so the corner
   matches the transparent track rather than the UA's opaque default. */
::-webkit-scrollbar-corner {
  background: transparent;
}


/* Source: packages/client/ui-theme/src/styles/corner-shape.css */
/* Smooth corner curvature for every rounded surface. Inside the support
 * guard, all corners curve along superellipse(1.5) — between a circular arc
 * (round = superellipse(1)) and a squircle (superellipse(2)) — instead of the
 * default arc; engines without corner-shape keep circular corners because the
 * token and the rule exist only inside the guard.
 *
 * corner-shape does not inherit, so the universal selector applies the token
 * to elements and their ::before/::after; other pseudo-elements (for example
 * the ::-webkit-scrollbar parts) stay circular.
 *
 * Full-round shapes opt out where they are declared: a superellipse deforms a
 * circle into a squircle and squares off capsule ends, so every effectively
 * uncapped radius (50%, 100%, or a pill radius far above the box size) pairs
 * `corner-shape: round` with its `border-radius` in the owning component
 * sheet. The corner-shape stylesheet spec enforces that pairing. */
@supports (corner-shape: superellipse(1.5)) {
  :host {
    --dsw-corner-shape: superellipse(1.5);
  }

  *,
  *::before,
  *::after {
    corner-shape: var(--dsw-corner-shape);
  }
}


/* Source: packages/client/ui-conversation/src/client/skeleton/ConversationRoot.module.css; CSS Module classes namespaced conv- */
.conv-root {
  position: relative; /* positioning context for slot-owned absolute chrome */
  display: flex;
  flex-direction: column;
  height: 100%;
  min-width: 0;
  background: var(--dsw-alias-bg-base);
}

/* 76px with its rule: the height of the Sidebar's tab strip and header row
   (ui-dockkit `.tabStrip` 38px + the pane header's 38px), so the two rules
   meet at the column edge. The rows add up to it — 10px top inset, the 30px
   title row, the tab strip's 10px margin, a 16px tab line, and its 9px bottom
   inset — so no row below may grow past its figure. */
.conv-header {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  flex: none;
  box-sizing: border-box;
  min-height: 76px;
  padding: 10px 28px 0 20px;
  border-bottom: 0.5px solid var(--dsw-alias-border-l3);
}

.conv-header:where(:not(:has(.conv-tabs))) {
  min-height: 0;
  padding-bottom: 10px;
}

/* Blank Sessions retain navigation controls without conversation title or tabs. */
.conv-headerBlank {
  min-height: 0;
  padding-bottom: 0;
  border-bottom: none;
}

.conv-headerBlank .conv-headerCorner {
  margin-left: auto;
}

/* Only the macOS titlebar needs reserved drag space before a Session exists. */
:host(:not([data-platform='darwin'])) .conv-headerSessionless {
  padding-top: 0;
}

:host(:not([data-platform='darwin'])) .conv-headerSessionless .conv-titleRow {
  min-height: 0;
}

/* macOS hiddenInset titlebar: the header block owns the window drag over its
   own box — title row plus the view tab strip, so the draggable geometry is the
   header's geometry and no frame band has to match its height. The header marks
   itself `data-window-drag` (ConversationHeader); below it the title-row clusters
   subtract their whole boxes, and individual controls are covered by the base.css
   interactive-element rule. A covering overlay lives beside #root
   (ui-settings-general), which puts it after this row in document order. */
[data-platform='darwin'] .conv-headerLeading,
[data-platform='darwin'] .conv-headerActions,
[data-platform='darwin'] .conv-headerUtilities,
[data-platform='darwin'] .conv-headerCorner {
  -webkit-app-region: no-drag;
}

.conv-titleRow {
  grid-column: 2;
  /* Anonymous inline-size container (CSS modules hash container-names per
     module, so occupants match the nearest container): header occupants such
     as the preset label and slot actions shed their text at row-width
     breakpoints. The minmax(0, 1fr) column sizes the row, so inline-size
     containment cannot collapse it. */
  container-type: inline-size;
  display: flex;
  align-items: center;
  gap: 0;
  min-height: 30px;
  /* Clears the frame's window-chrome band (traffic lights + shell.leading
     controls, ui-layout AppFrame) when it is published; the header already
     pads 20px of it. Zero everywhere else (the fallback makes the max
     negative). */
  padding-inline-start: max(0px, calc(var(--dsh-frame-leading-clearance, 0px) - 20px));
}

.conv-titleCluster {
  display: flex;
  flex: 1;
  align-items: center;
  gap: 10px;
  min-width: 0;
}

/* The auto grid column collapses with an empty or CSS-hidden occupant.
   The occupant owns its trailing gap so hidden controls reserve no space. */
.conv-headerLeading {
  grid-column: 1;
  grid-row: 1;
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
}

.conv-crumbs {
  display: flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
  overflow: hidden;
  white-space: nowrap;
}

.conv-crumbSeg {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-width: 0;
}

.conv-crumbSep {
  /* figma: "/" separators are 14px caption gray (75:7903), one tint lighter than crumb text. */
  color: var(--dsw-alias-label-caption);
  font-size: 14px;
  line-height: 20px;
}

.conv-crumb {
  display: inline-block;
  max-width: 220px;
  overflow: hidden;
  padding: 4px 8px;
  border: none;
  border-radius: var(--dsw-radius-md);
  background: transparent;
  font-size: 14px;
  line-height: 20px;
  color: var(--dsw-alias-label-tertiary);
  text-overflow: ellipsis;
  white-space: nowrap;
  cursor: pointer;
}

.conv-crumbSubagent {
  font-size: 12px;
  line-height: 18px;
}

button.conv-crumb:hover {
  background: var(--dsw-alias-interactive-bg-hover);
}

.conv-crumbCurrent {
  font-weight: 500;
  color: var(--dsw-alias-label-primary);
  cursor: default;
}

.conv-headerActions {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
}

.conv-headerUtilities {
  display: flex;
  flex: none;
  align-items: center;
  gap: 8px;
  margin-left: 20px;
}

.conv-headerUtilities:empty {
  display: none;
}

/* The far-right corner seat reaches 16px into the header's 28px right padding,
   so its control sits past the utilities' edge; it is laid out only while its
   occupant renders something. Its left margin equals the utilities' 8px gap so
   the header's trailing controls space evenly. */
.conv-headerCorner {
  display: flex;
  flex: none;
  align-items: center;
  margin-left: 8px;
  margin-right: -16px;
}

.conv-headerCorner:empty {
  display: none;
}

/* figma Tab_Group 34:11441: 35px strip, gap 36, pad-left 8, tabs bottom-aligned.
   Positioned above the header's own paint, so the active bar covers the rule. */
.conv-tabs {
  grid-column: 1 / -1;
  position: relative;
  z-index: 1;
  display: flex;
  gap: 36px;
  margin-top: 10px;
  padding-left: 8px;
}

/* figma .Tab 34:11442: 13/16 text (figma wt510, rendered 500). The 2px bar
   reaches 1px past the tab's box to end flush with the header's bottom edge,
   sitting over the rule. */
.conv-tab {
  position: relative;
  padding: 0 0 9px;
  border: none;
  background: transparent;
  font-size: 13px;
  line-height: 16px;
  font-weight: 500;
  color: var(--dsw-alias-label-tertiary);
  cursor: pointer;
}

.conv-tab::after {
  content: '';
  position: absolute;
  right: 0;
  bottom: -1px;
  left: 0;
  height: 2px;
  border-radius: 2px;
  background: transparent;
}

/* Selected tab is blue, not ink: brand-primary resolves to neutral black in
   this token sheet, so the selected state rides the business blue — the
   nearest semantic token that stays blue in both themes. */
.conv-tabActive {
  color: var(--dsw-alias-state-business-primary);
}

.conv-tabActive::after {
  background: var(--dsw-alias-state-business-primary);
}

.conv-viewArea {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
}

/* Width handles: 10px col-resize strips beside the transcript, absolute in
   .body (NOT the scrollport: an absolute strip there would extend the
   scrollable range; NOT .root: a strip from the column top would paint its
   glow through the header's transparent background). The inner edge sits
   24px outside the content column and the strip extends 10px outward; the
   outer edge is clamped to keep a 24px safe zone against the
   column edges (sidebar side and scrollbar side stay drag-free). When the
   margin cannot fit inset + strip + safe zone the computed width goes
   negative and the strip resolves to zero — no mispositioned hit area on
   narrow columns. Known half-scrollbar (~4px) centering offset vs the
   gutter-reserved content box is accepted: it consumes part of the 10px
   strip but remains within it. */
.conv-widthHandle {
  position: absolute;
  top: 0;
  bottom: 0;
  /* Concrete overflow content establishes z-index 1, while the sticky
     composer remains above both layers. */
  z-index: 0;
  width: min(
    10px,
    calc((100% - var(--dsh-chat-content-width)) / 2 - 24px - 24px)
  );
  cursor: col-resize;
}

.conv-widthHandle[data-side='left'] {
  right: calc(50% + var(--dsh-chat-content-width) / 2 + 24px);
}

.conv-widthHandle[data-side='right'] {
  left: calc(50% + var(--dsh-chat-content-width) / 2 + 24px);
}

/* The glow: a short 2px bar following the captured pointer's Y, centered in the strip
   (29px from the content column), not a full-height rule — a 16px solid core
   centered on the pointer
   (published during drag as --dsh-width-handle-pointer-y), fading to
   transparent over 28px each side (72px total). A solid CORE, not a single
   solid stop: a lone peak washes out over the fade. The resting scrollbar
   tint keeps this secondary affordance quiet in both themes. Before the first
   drag move the fallback centers the glow at 50% height; hover leaves its position unchanged. */
.conv-widthHandle::after {
  content: '';
  position: absolute;
  top: 0;
  bottom: 0;
  width: 2px;
  border-radius: 2px;
  background: linear-gradient(
    to bottom,
    transparent calc(var(--dsh-width-handle-pointer-y, 50%) - 36px),
    var(--dsw-alias-scrollbar-bg-l1) calc(var(--dsh-width-handle-pointer-y, 50%) - 8px),
    var(--dsw-alias-scrollbar-bg-l1) calc(var(--dsh-width-handle-pointer-y, 50%) + 8px),
    transparent calc(var(--dsh-width-handle-pointer-y, 50%) + 36px)
  );
  opacity: 0;
  pointer-events: none;
}

.conv-widthHandle[data-side='left']::after {
  right: 4px;
}

.conv-widthHandle[data-side='right']::after {
  left: 4px;
}

.conv-widthHandle:hover::after,
.conv-widthHandle[data-dragging]::after {
  opacity: 1;
}

/* A drag starts above the composer band. Pointer capture keeps it active when
   crossing the footer; lift only the active handle so its indicator remains
   visible without making the resting footer gutter draggable. */
.conv-widthHandle[data-dragging] {
  z-index: 8;
}

/* Views that elect a composer overlay (trajectory etc.) own their full-bleed
   scrollers; the strips would sit over their content and steal clicks. */
.conv-root:has([data-conversation-composer-overlay]) .conv-widthHandle {
  display: none;
}

/* Composer context stack (Figma 9:937): standalone dock cards share one
   rhythm above the input card. */
.conv-composerStack {
  /* Horizontal geometry (card width, clearance, dock inset) rides the shared
     .root variables above so takeover siblings match the stack. */
  --dsh-composer-stack-gap: 6px;

  display: flex;
  flex-direction: column;
  gap: var(--dsh-composer-stack-gap);
}

/* Common seat for the composer chain (fallback + elected overlay siblings). */
.conv-composerSeat {
  display: flex;
  flex: none;
  flex-direction: column;
  /* One cap for every scrolling text region a composer seat can hold: the
     InputBar draft (figma Input 75:8208 max 14 lines × 24px line) and the
     takeover panels' bodies top out at the same height, so electing a
     takeover never grows the footer past the card it replaces. Declared on
     the seat because it is the chain's only shared ancestor — fallback and
     elected overlay are siblings — and custom properties inherit down to
     whichever entry is mounted. */
  --dsh-composer-text-max-height: 336px;
}

/* Active phase: header is ordinary column chrome above the scrollport (not
   sticky). The scroll body holds the transcript and the sticky composer seat
   so wheel over the footer moves the flow. */
.conv-root[data-phase='active'] {
  overflow: hidden;
}

.conv-root[data-phase='active'] .conv-header {
  flex: none;
}

/* Band below the header: the scrollport plus the width handles. Anchoring the
   handles here keeps their full-height strips and glow under the header's
   bottom edge at every header height. */
.conv-body {
  position: relative;
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;

  /* Shared width axis for the transcript, dock cards, composer, and takeover
     cards. Main width controls publish the live body width and optional user
     preference; embedded occurrences override this adaptive axis below. */
  --dsh-chat-content-width: var(
    --dsh-chat-user-width,
    clamp(680px, calc(var(--dsh-conversation-column-width, 0px) * 0.64), 920px)
  );
  --dsh-composer-card-max-width: calc(var(--dsh-chat-content-width) + 32px);
  --dsh-composer-side-clearance: 16px;
  --dsh-composer-dock-inset: 8px;
}

.conv-embeddedBody {
  overflow: hidden;
  --dsh-chat-content-width: min(calc(100% - 32px), 920px);
  --dsh-composer-card-max-width: min(calc(100% - 16px), 952px);
  --dsh-composer-side-clearance: 8px;
  --dsh-composer-dock-inset: 8px;
}

.conv-scrollBody {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-height: 0;
  /* The product-wide 2px scrollbar offset (ui-workspace WorkspaceBrowser
     `.list`, ui-sidebar-files FilesBody `.body`): the bar sits 2px clear of
     the column's edge instead of flush against it. */
  margin-right: 2px;
  overflow-y: auto;
  /* Reserved unconditionally: the composer seat rides this box's content box in
     Chat and its padding box under a view's composer overlay, so an `auto`
     gutter moves the input card sideways by the bar's width whenever the two
     differ ([decision](../../../../../../.agents/notes/archived/bug-fix/2026-08-04-composer-tab-gutter-reservation.md)). */
  scrollbar-gutter: stable;
}

/* The bar also stops 2px short of the scroller's ends, matching its 2px edge
   offset. WebKit-only: the Firefox path has no track to inset. */
.conv-scrollBody::-webkit-scrollbar-track {
  margin: 2px;
}

.conv-root[data-phase='active'] .conv-viewArea,
.conv-embeddedBody[data-content-phase='active'] .conv-viewArea {
  flex: 1 0 auto;
  min-height: auto;
}

.conv-root[data-phase='active'] .conv-composerSeat,
.conv-embeddedBody[data-content-phase='active'] .conv-composerSeat {
  position: sticky;
  bottom: 0;
  /* Above markdown CodeBlock sticky banners (z-index 6) so the footer never
     paints under a sticking code header while scrolling. The pinned compaction
     header (MessageItem.module.css, ui-chat) and the turn-navigation rail slot
     (TurnNavigator.module.css, ui-chat) also take 7 to clear the same banners.
     Among elements of equal rank the later one in DOM order wins, so the
     composer stays above the pinned header on the extreme small-viewport
     overlap and the pinned header stays above the rail. */
  z-index: 7;
  /* Input mask (figma 1205:27463): transcript fades out under a FIXED 36px
     band at the seat's top (the figma 24% of the resting ~150px composer),
     solid below — px stops, not %, so a growing draft only widens the solid
     region and the fade band never stretches. The 0px stop is bg-base at
     zero alpha (not white, which the figma export hardcodes) so both themes
     fade from their own base. */
  background: linear-gradient(
    180deg,
    color-mix(in srgb, var(--dsw-alias-bg-base) 0%, transparent) 0px,
    var(--dsw-alias-bg-base) 36px
  );
}

/* Lite keeps the composer below the transcript scrollport. It remains a
   positioned footer for the existing stacking rules without sticking to a
   scroller it no longer belongs to. */
:host([data-dsh-lite]) .conv-body > .conv-composerSeat {
  position: relative;
  bottom: auto;
}

/* An open @/slash menu (data-trigger-menu, ui-input-trigger) renders inside
   the input card, so the seat's stacking context caps its z-index; lift the
   seat above the back-to-bottom control (z-index 8, ui-chat ChatView) while
   the menu is open. The steady state stays 7 so the control keeps painting
   over the card. */
.conv-root[data-phase='active'] .conv-composerSeat:has([data-trigger-menu]) {
  z-index: 9;
}

/* Views may opt into a composer overlay while ConversationRoot retains
   ownership of the seat geometry and its active-phase precedence. */
.conv-scrollBody:has([data-conversation-composer-overlay]) {
  position: relative;
  /* A clipping box nothing scrolls out of, stated as a scroll container on both
     axes rather than `overflow: hidden`: a single-axis scroller computes the
     other axis to `auto`, and the seat's absolute positioning below needs the
     box to stay a containing block in every engine. */
  overflow-x: hidden;
  overflow-y: auto;
  /* The view owns its own scrollers (the trajectory ledger scrolls inside the
     view), so this box never scrolls here; reserving a gutter would only
     narrow the view's content by the bar's width. Chat keeps the reservation
     on the same element, so the seat below compensates with the bar's width
     ([decision](../../../../../../.agents/notes/archived/bug-fix/2026-08-04-composer-tab-gutter-reservation.md)). */
  scrollbar-gutter: auto;
}

.conv-scrollBody:has([data-conversation-composer-overlay]) > [data-slot='conversation.session'] > .conv-viewArea {
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
}

.conv-scrollBody:has([data-conversation-composer-overlay]) > .conv-composerSeat {
  position: absolute;
  /* Chat's seat rides this box's content box, which its own scrolling shortens
     by the bar's width; the overlay seat is against the padding box, so it
     must give back the same width to keep the input card in place across
     tabs. Reads ui-theme's --dsh-scrollbar-width, which mirrors the WebKit
     bar's layout width. Chat reserves the engine-resolved width, so on an
     engine where the resolved width differs from this fixed 8px the card
     drifts by half the difference — accepted residual risk, recorded in
     ([decision](../../../../../../.agents/notes/archived/bug-fix/2026-08-12-composer-overlay-seat-width-compensation.md)). */
  right: var(--dsh-scrollbar-width);
  bottom: 0;
  left: 0;
}

/* Hero phase: the composer stack (hero chrome + workspace row + card) is
   flex-centered in the column; composer phase docks it at the bottom. Flex,
   NOT absolute+transform: a transform would make this box the containing
   block for position:fixed descendants (pickers/modals), shrinking them. */
.conv-composerHero {
  align-self: center;
  /* figma 75:8208 drew 12 between all three rows; the workspace row now sits
     8 above the card (its margin-top restores 12 under the hero chrome). */
  gap: 8px;
  /* Foot inside the centered box floats the stack a bit above true center. */
  padding-bottom: 32px;
  /* Card cap + both clearances: the hero input card lands at exactly the same
     width as the docked composer at every viewport. */
  width: min(calc(var(--dsh-composer-card-max-width) + 2 * var(--dsh-composer-side-clearance)), 100%);
  z-index: 1;
}

.conv-heroWorkspaceRow {
  display: flex;
  align-items: center;
  gap: 2px;
  min-width: 0;
  margin-top: 4px;
  /* figma drew px 8; left nudged +12 so the chip's folder glyph lines up
     closer to the card's inner controls below; right keeps the trailing
     preset seat off the card edge. */
  padding: 0 16px 0 20px;
}

/* Hero: the full shell's composer sits inside the session scroll body; center
   there so the tree seat matches active (sticky footer) without a Root
   remount. */
.conv-root[data-phase='hero'] .conv-scrollBody,
.conv-embeddedBody[data-content-phase='hero'] .conv-scrollBody {
  justify-content: center;
  overflow-y: auto;
}

/* Lite has no Hero chrome above the blank composer. Its sibling seat already
   follows the scrollport at the bottom of the body. */
:host([data-dsh-lite]) .conv-root[data-phase='hero'] .conv-composerHero,
:host([data-dsh-lite]) .conv-embeddedBody[data-content-phase='hero'] .conv-composerHero {
  padding-bottom: 4px;
}

/* Settling (session replaying, hero/docked unknown): keep the composer seat
   mounted but invisible so no wrong layout flashes before the phase lands. */
.conv-root[data-phase='settling'] .conv-composerSeat,
.conv-embeddedBody[data-content-phase='settling'] .conv-composerSeat {
  visibility: hidden;
}


/* Source: packages/client/ui-conversation/src/client/skeleton/InputBar.module.css; CSS Module classes namespaced input- */

.input-root {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* Side pads ride the shared clearance (figma Input_Bottom drew L32/R32/B8;
     the sides narrow with the shared width axis); the bottom gradient mask
     is owned by the chat scroller. No top pad: the composer stack's gap owns
     the space above; the status strip still carries its own margin. */
  padding: 0 var(--dsh-composer-side-clearance) 4px;
}

.input-dock {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  max-width: 100%;
  padding-top: 4px;
}

.input-hero .input-dock:empty {
  display: none;
}

/* Lite keeps the native below-card dock in layout and hides its contents. */
.input-dock[data-lite-dock] {
  visibility: hidden;
  pointer-events: none;
}

/* A theme-owned blank line gives an empty Lite dock its intrinsic row size.
   This follows the typography token instead of fixing a Lite-only height. */
.input-dock[data-lite-dock]::before {
  content: '\00a0';
  font: var(--dsw-font-xs-13);
}

/* The full Hero removes a truly empty dock. Lite retains that native row. */
.input-hero .input-dock[data-lite-dock]:empty {
  display: flex;
}

.input-hero {
  /* No bottom pad in the centered hero, but the side clearance must survive:
     the hero wrapper is full-width on narrow viewports, so this padding is
     the only thing keeping the card off the edges there. */
  padding: 0 var(--dsh-composer-side-clearance);
}

.input-notice {
  width: 100%;
  max-width: var(--dsh-composer-card-max-width);
  margin-bottom: 6px;
  padding: 4px 8px;
  border-radius: var(--dsw-radius-md);
  background: var(--dsw-alias-interactive-bg-hover);
  color: var(--dsw-alias-label-secondary);
  font-size: 12px;
  line-height: 18px;
}

.input-card {
  box-sizing: border-box;
  position: relative; /* overlay anchor positioning context */
  display: flex;
  flex-direction: column;
  /* figma Input 75:8208: 12px between the text area and the button row; the
     card's top pad before .InputText tightened from the drawn 10 to 8. */
  gap: 12px;
  width: 100%;
  max-width: var(--dsh-composer-card-max-width);
  padding-top: 8px;
  /* Input stroke: the light neutral (l2, one step above the menus' l1),
     drawn as the elevation hairline so it costs no layout; the shadow is the
     soft elevation tier. Fill: the input surface token (elevated in dark). */
  border: 0;
  --dsw-elevation-stroke-color: var(--dsw-alias-border-l2);
  border-radius: var(--dsw-radius-panel);
  background: var(--dsw-specific-input-major);
  box-shadow: var(--dsw-elevation-soft);
  /* The draft text follows the Settings font-size preference (the textarea,
     mirror, and backdrop all inherit from here, so the three layers stay in
     step); the line height keeps the default 10px leading via the shared px
     delta. */
  font-size: var(--dsh-content-font-size, 14px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  /* Elevated surface in dark, same as the menus: the draft scrollport inside
     scrolls once the composer hits its height cap, so the thumb takes the l2
     pair. Declared on the card because the elevation belongs to the surface,
     and the custom properties inherit down to the box that actually scrolls
     (see ui-theme styles/scrollbar.css for the rebinding contract). */
  --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);
  --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);
}

/* Mobile Safari zooms focused editable content below 16px. Lite is embedded
   in a fixed shell, so keep the actual draft size at least 16px without
   disabling page zoom or reducing larger Settings choices. */
@container dsh-surface (max-width: 767px) {
  :host([data-dsh-lite]) .input-card {
    font-size: max(16px, var(--dsh-content-font-size, 14px));
  }
}

/* No-workspace trigger state: an inset 1px dashed outline marks the card as a
   workspace picker rather than a live composer. Keeping the complete stroke
   inside the rounded box prevents clipped corner pixels from reading heavier. */
.input-cardWorkspaceTrigger {
  --dsw-elevation-stroke-color: transparent;
  cursor: pointer;
}

.input-cardWorkspaceTrigger::after {
  content: '';
  position: absolute;
  inset: 0;
  box-sizing: border-box;
  border: 1px dashed currentColor;
  border-radius: var(--dsw-radius-panel);
  color: var(--dsw-alias-border-l4);
  transition: color 100ms ease;
  pointer-events: none;
}

/* Disabled toolbar controls neither receive nor swallow clicks in the trigger
   state: pointer events fall through to the card's own click handler, making
   the whole card one pick target. */
.input-cardWorkspaceTrigger :disabled {
  pointer-events: none;
}

.input-cardWorkspaceTrigger:hover::after {
  color: var(--dsw-alias-state-business-primary);
}

.input-accessory {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 12px 0;
}

/* Floating overlay anchor (menu / popupSelect shell): entries position
   themselves against the card (bottom: 100% + gap); closed entries render null. */
.input-overlayAnchor {
  position: absolute;
  inset: 0 0 auto;
  height: 0;
}

/* The draft's scrollport, and the ONLY scrolling box in the composer. The
   contenteditable grows with its content inside; the 14-line cap lives here
   because this is the box the cap describes. */
.input-scroll {
  max-height: var(--dsh-composer-text-max-height);
  overflow-y: auto;
  /* Keeps the bar off the card's right border; .input's right pad gives the
     4px back so the text column is unchanged. */
  margin-right: 4px;
}

/* The card's corner arc still overlaps the scrollport's top (8px top
   pad reaches only y=8): start the thumb's travel below the arc so it never
   pokes outside the capsule. WebKit-path only; Firefox's thin bar has no
   track margin, an accepted remainder. */
.input-scroll::-webkit-scrollbar-track {
  margin-top: 8px;
}

/* Auto-grow anchor: the contenteditable is in normal flow and sets the
   draft's height; the placeholder rides it absolutely. */
.input-grow {
  position: relative;
}

/* Machine pending dot (adjudicating / submitting). */
.input-pending {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  corner-shape: round;
  background: var(--dsw-alias-state-business-primary);
  animation: input-pending 1s ease-in-out infinite alternate;
}

@keyframes input-pending {
  from { opacity: 0.35; }
  to { opacity: 1; }
}

/* The contenteditable draft surface (grows with its content; .scroll caps
   and scrolls it). figma .InputText 34:10434 drew pl 16 / pr 12 / pt 4; the
   left pad tightened to 14, and the right pad is 8 here plus .scroll's 4px
   bar inset. */
.input-input {
  box-sizing: border-box;
  /* Docked floor: one 24px line + 4px top pad = 28 content height; 36 leaves
     an 8px breath below the line (the hero keeps its own 52px floor below). */
  min-height: 36px;
  padding: 4px 8px 0 14px;
  font-family: var(--dsw-font-family);
  font-size: inherit;
  line-height: inherit;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
  outline: none;
  color: var(--dsw-alias-label-primary);
  /* Business blue, not brand-primary: that token resolves to ink in this sheet. */
  caret-color: var(--dsw-alias-state-business-primary);
}

/* Lexical paragraphs are <p> blocks: strip the UA margins so the surface
   keeps the textarea's line rhythm. */
.input-input p {
  margin: 0;
}

/* Claim ghost hint as generated content after the last paragraph: the bar
   sets --dsh-composer-hint (a quoted string) while the claim's args are
   blank; without the variable the declaration is invalid and nothing shows. */
.input-input p:last-child::after {
  content: var(--dsh-composer-hint);
  color: var(--dsw-alias-label-caption);
}

.input-input[data-composer-composing] p:last-child::after {
  content: none;
}

.input-input[data-composer-composing] + .input-placeholder {
  visibility: hidden;
}

/* figma 34:10434: #ADB2B8 light / #81858C dark — the caption pair exactly.
   Insets mirror .input's pads (the other right 4px sits on .scroll). One
   ellipsized line: a wrapped second line would clip against the docked
   36px floor. */
.input-placeholder {
  position: absolute;
  inset: 4px 8px auto 14px;
  color: var(--dsw-alias-label-caption);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  pointer-events: none;
  user-select: none;
}

.input-inputDisabled {
  color: var(--dsw-alias-label-tertiary);
  cursor: not-allowed;
}

.input-input[aria-haspopup='menu'] {
  cursor: pointer;
}

/* Hero (centered empty-state) keeps the 2-line floor (figma min-h 52 = ~2 × 24
   line + 4pt); the docked composer collapses to the content height. */
.input-hero .input-input {
  min-height: 52px;
}

/* The hero's 52px floor fits two lines, so its placeholder clamps at two
   instead of the docked single line. */
.input-hero .input-placeholder {
  white-space: normal;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

/* Toolbar: attach + Plan + Read-only on the left; model + send on the right
   (figma Input_Bottom chrome). */
.input-row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  /* 2px moved from the bottom pad to the top: the whole control row sits 2px
     lower in the card (it read too high against the textarea) while the
     controls' own centering stays untouched. */
  padding: 2px 8px 6px;
  min-width: 0;
  /* Size container so the chips inside can collapse to icon-only when the
     card runs out of row width (PermissionSelect @container rule). Anonymous
     on purpose: CSS modules hash container-name per module, so a name declared
     here can never match a query in another module's sheet. */
  container-type: inline-size;
}

.input-row[data-model-compact] {
  --dsh-composer-model-text-display: none;
  --dsh-composer-model-icon-display: block;
}

.input-tools,
.input-modes,
.input-trailing {
  display: flex;
  align-items: center;
  min-width: 0;
}

/* figma 75:8208 drew 16 between + and the mode chips and 4 between Plan /
   Read-only; both gaps settled on 12 so the pill chips read as separate
   controls without drifting from the + control. */
.input-tools {
  gap: 12px;
}

.input-modes {
  gap: 12px;
}

.input-trailing {
  flex: none;
  /* Wrap keeps the left mode chips and the right controls apart when the card
     runs out of row width: the trailing group (model + send) moves to its own
     line instead of the left group shrinking until its chip overlaps the
     model trigger (external:107). The auto margin re-anchors it right on the
     wrapped line; on a single line space-between already pins it right. */
  margin-left: auto;
  gap: 12px;
}

/* Compact spacing preserves room for the fixed-width controls in narrow cards. */
@container (max-width: 560px) {
  .input-tools,
  .input-modes,
  .input-trailing {
    gap: 8px;
  }
}

/* Attach circle (figma + control): 28px, selector fill, primary glyph. */
.input-add {
  display: grid;
  place-items: center;
  flex: none;
  width: 28px;
  height: 28px;
  border: none;
  border-radius: 999px;
  corner-shape: round;
  background: var(--dsw-specific-selector);
  color: var(--dsw-alias-label-primary);
  cursor: pointer;
}

.input-add:hover:not(:disabled) {
  background: var(--dsw-alias-interactive-bg-hover-solid);
}

.input-add:disabled {
  opacity: 0.5;
  cursor: default;
}

/* At 14px, a two-unit SVG stroke renders at 1.75px and matches the Lite
   send arrow's two-unit stem without changing the full DSH icon weight. */
.input-liteAddIcon {
  stroke-width: 2px;
}

/* Plan / Read-only / model — native <select>, chip-like closed chrome
   (figma ToggleButton: 13/20 medium secondary, 12px chevron). */
.input-select {
  max-width: 220px;
  height: 28px;
  padding: 0 20px 0 8px;
  border: none;
  border-radius: var(--dsw-radius-sm);
  outline: none;
  background-color: transparent;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12' fill='none'%3E%3Cpath d='M3 4.5L6 7.5L9 4.5' stroke='%2381858C' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 4px center;
  background-size: 12px 12px;
  color: var(--dsw-alias-label-secondary);
  font-size: 13px;
  line-height: 20px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  appearance: none;
}

.input-select:hover:not(:disabled) {
  background-color: var(--dsw-alias-interactive-bg-hover);
}

.input-select:disabled {
  opacity: 0.5;
  cursor: default;
}

/* Primary send (figma IconButton 34:10465): 34px circle, #3964FE light /
   #679EFE dark — the info-fill pair (500→400), NOT button-primary (ink);
   white glyph; empty text = 0.4 opacity. */
.input-primary {
  display: grid;
  place-items: center;
  flex: none;
  width: 34px;
  height: 34px;
  border: none;
  border-radius: 999px;
  corner-shape: round;
  background: var(--dsw-alias-button-info-fill);
  /* Static white, not the foreground token: the arrow stays white on the blue
     fill in both themes (design 34:10465). */
  color: #fff;
  cursor: pointer;
  transition: background-color 100ms ease;
  /* Opts out of the row's 2px downward shift (.row top pad): the send circle
     keeps its original seat while the smaller chips sit lower. Transform, not
     margin, so flex centering math is untouched. */
  transform: translateY(-2px);
}

.input-primary:hover:not(:disabled) {
  background: var(--dsw-alias-button-info-hover);
}

.input-primary:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Lite aligns the two circular edge controls and keeps its product accent
   independent of the selected light or dark palette. */
:host([data-dsh-lite]) .input-primary {
  width: 28px;
  height: 28px;
  background: var(--dsw-alias-lite-accent);
  color: var(--dsw-alias-lite-accent-foreground);
  transform: none;
}

:host([data-dsh-lite]) .input-primary:hover:not(:disabled) {
  background: var(--dsw-alias-lite-accent);
}

:host([data-dsh-lite]) .input-primary:disabled {
  background: var(--dsw-alias-button-primary-dimmed);
  color: var(--dsw-alias-label-caption);
  opacity: 1;
}

.input-retry {
  margin-left: 8px;
  padding: 1px 8px;
  border: 1px solid currentColor;
  border-radius: var(--dsw-radius-sm);
  background: transparent;
  color: inherit;
  font-size: 12px;
  cursor: pointer;
}

.input-standardControls { display: flex; align-items: center; gap: 12px; min-width: 0; }
.input-tools[hidden], .input-standardControls[hidden] { display: none; }
.input-trailingActive { flex: 1; margin-left: 0; }
.input-activity { display: flex; align-items: center; flex: none; }
.input-activity:empty { display: none; }
.input-activityExpanded { flex: 1; min-width: 0; }


/* Source: packages/client/ui-chat/src/client/chat/ChatView.module.css; CSS Module classes namespaced chat- */
.chat-frame {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;
  /* Floating controls query this frame outside the clipped transcript. */
  container-type: inline-size;
}

.chat-root {
  position: relative;
  display: flex;
  flex-direction: column;
  min-height: 0;
  flex: 1 1 auto;

  overflow-x: visible;
  overflow-y: clip;
}

.chat-scroll {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  /* Sides = composer clearance + 16px: on narrow viewports the transcript
     stays exactly 32px narrower than the input card (the shared width rule). */
  padding: 16px calc(var(--dsh-composer-side-clearance) + 16px);
  /* Inline-size query container: wide markdown tables size their breakout
     against this box's content width (100cqw in AssistantMarkdown's
     md-table-wide rule) — the CSS stand-in for deepsuite chat's JS-measured
     --dsl-virtual-list-width. */
  container-type: inline-size;
}

.chat-root[data-chat-following-tail] .chat-scroll,
[data-conversation-scroll]:has(.chat-root[data-chat-following-tail]) {
  overflow-anchor: none;
}

[data-conversation-scroll] .chat-frame,
[data-conversation-scroll] .chat-root {
  flex: 0 0 auto;
  min-height: auto;
  height: auto;
}

[data-conversation-scroll] .chat-scroll {
  overflow: visible;
  flex: 0 0 auto;
  min-height: auto;
}

/* Message column: shared chat width (ConversationRoot --dsh-chat-content-width),
   centered on the same axis as the input box (which caps at chat + 16px); the
   scroller itself stays full-bleed. */
.chat-column {
  max-width: var(--dsh-chat-content-width);
  width: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
}

/* `hidden="until-found"` retains a zero-height box so browser find can reveal
   its subtree. Direct Chat Node Seats and auxiliary rows share one flow;
   hidden and empty Seats do not contribute spacing. */
.chat-column > :not([hidden]):not(.chat-flowItem:empty)
  ~ :not([hidden]):not(.chat-flowItem:empty) {
  margin-top: var(--dsh-chat-flow-gap, 16px);
}

/* Settled-flow identity boundary. It is neutral until it becomes the natural
   measurement/mount unit for a virtualizer without changing the column gap. */
.chat-flowItem {
  min-width: 0;
}

/* A closed process reads as one summary immediately followed by its answer.
   Expanded process rows return to the ordinary 16px rhythm. */
.chat-flowItem[data-turn-process-answer] {
  --dsh-chat-flow-gap: 8px;
}

/* Empty Seats retain ordered layout positions for Turn lookup without
   contributing height or the sibling gap. */
.chat-flowItem:empty {
  height: 0;
}

.chat-callRow {
  border-radius: var(--dsw-radius-sm);
}

/* Selection still sets data-selected for details linkage; no outline —
   tool rows match Think chrome (no selected ring). */

.chat-hint {
  color: var(--dsw-alias-label-tertiary);
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(18px + var(--dsh-content-font-delta-secondary, 0px));
}

.chat-openError {
  color: var(--dsw-alias-state-error-primary);
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(18px + var(--dsh-content-font-delta-secondary, 0px));
}

.chat-older {
  display: flex;
  justify-content: center;
}

.chat-older button {
  border: none;
  border-radius: var(--dsw-radius-sm);
  padding: 4px 12px;
  font-size: 12px;
  color: var(--dsw-alias-label-secondary);
  background: var(--dsw-alias-interactive-bg-hover-solid);
  cursor: pointer;
}

.chat-older button:disabled {
  cursor: default;
  opacity: 0.6;
}

/* Floating controls sit outside the clipped transcript. A standalone Chat
   anchors them to its frame; the shared host supplies the sticky scrollport. */
.chat-toBottomSlot {
  position: absolute;
  right: 0;
  bottom: 16px;
  left: 0;
  /* Above the sticky composer (z-index 7) so the control stays clickable and
     visible over the input card. Exception: while an @/slash menu is open the
     seat lifts to 9 (ui-conversation ConversationRoot) so the menu is never
     covered by this control. */
  z-index: 8;
  height: 0;
  display: flex;
  justify-content: flex-end;
  padding-right: max(
    calc(var(--dsh-composer-side-clearance) + 16px),
    calc((100% - var(--dsh-chat-content-width)) / 2)
  );
  pointer-events: none;
}

[data-conversation-scroll] .chat-toBottomSlot {
  position: sticky;
  /* Clears the sticky composer stack (docks + input card + stats): the live
     height rides --dsh-composer-height (ConversationRoot's seat observer) so
     the control follows a growing textarea; the fallback covers the first
     paint before the observer fires. */
  bottom: calc(var(--dsh-composer-height, 152px) + 16px);
}

.chat-toBottom {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  margin-top: -34px;
  padding: 0;
  border: 0;
  --dsw-elevation-stroke-color: var(--dsw-alias-border-l3);
  border-radius: 100px;
  corner-shape: round;
  color: var(--dsw-alias-label-primary);
  background: var(--dsw-alias-button-floating-fill);
  box-shadow: var(--dsw-elevation-panel);
  cursor: pointer;
  pointer-events: auto;
}

.chat-toBottom:hover {
  background: var(--dsw-alias-button-floating-hover);
}

/* Host open-path refusal: same dialog family as the workspace folder error. */
.chat-modalAction {
  min-width: 72px;
}


/* Source: packages/client/ui-chat/src/client/chat/MessageItem.module.css; CSS Module classes namespaced msg- */
/* User messages align their bubble and action row to the right. */

.msg-userRow {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 6px;
}

.msg-userStack {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  min-width: 0;
  /* The figma 525px cap held as a share of the width axis (525/748 ≈ 0.702):
     resolves to the original 525px on the default column and widens with a
     dragged or adaptive column. The 748px fallback covers mounts outside the
     conversation column, where the axis variable is absent. */
  max-width: min(calc(var(--dsh-chat-content-width, 748px) * 0.702), 82%);
}
.msg-bubble {
  /* Figma's 525px cap held as a share of the width axis (525/748 ≈ 0.702) so
     the bubble widens with a user-dragged or adaptive column; percentage
     keeps narrow windows sane. */
  max-width: 100%;
  background: var(--dsw-specific-bubble);
  border-radius: var(--dsw-radius-xl);
  /* 42px single-line bubble at the default size: 22 line + 10 vertical
     padding each side; the Settings font-size preference moves size and line
     height together through the body-published axis. */
  padding: 10px 16px;
  font-size: var(--dsh-content-font-size, 14px);
  line-height: calc(22px + var(--dsh-content-font-delta, 0px));
  color: var(--dsw-alias-label-primary);
  /* The projected user text is inline runs; the bubble owns wrapping so a
     decorated single-line message stays one line. */
  white-space: pre-wrap;
  word-break: break-word;
}

/* The embedded Lite surface uses its fixed product accent for authored
   messages in either palette. Reference chips inherit the white message
   label instead of bringing the standard link blue into the bubble. */
:host([data-dsh-lite]) .msg-bubble {
  background: var(--dsw-alias-lite-accent);
  color: var(--dsw-alias-lite-accent-foreground);
}

:host([data-dsh-lite]) .msg-bubble [data-ref-chip] {
  color: inherit;
}

:host([data-dsh-lite]) .msg-bubble [data-ref-chip]:is(:hover, :focus) {
  text-decoration-color: currentcolor;
}

.msg-referenceSummary {
  color: var(--dsw-alias-label-tertiary);
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(18px + var(--dsh-content-font-delta-secondary, 0px));
}
.msg-contextRow {
  padding: 2px 0;
}

/* Compaction marker: one dim 24px row with a context icon at rest and a
   hover/focus disclosure for the summary body. Dimmed title (not
   label-primary) — the row is a boundary notice, not conversation content. */
.msg-compactionRow {
  /* The toggle's line, and the band a pinned toggle occupies. The button's
     height and the offset that holds a summary's code banner below that band
     are the same measurement, so both read it from here. */
  --dsh-compaction-header-height: calc(24px + var(--dsh-content-font-delta, 0px));
  padding: 2px 0;
}

.msg-compactionButton {
  display: flex;
  align-items: center;
  width: 100%;
  height: var(--dsh-compaction-header-height);
  min-width: 0;
  padding: 0;
  border: none;
  border-radius: var(--dsw-radius-sm);
  background: none;
  color: inherit;
  font: inherit;
  text-align: left;
}

/* The summary body flows uncapped with the page, so a long checkpoint summary
   carries this toggle off the top of the viewport. Pin it to the conversation
   scroll container's top while the row is open (the body is a sibling rendered
   only when expanded); the base background masks the prose scrolling under it.
   The square corners apply for as long as the row is open, pinned or not: the
   fill is what masks the prose, and rounded corners would leave that prose visible
   in the corners. z-index outranks the markdown code block's own sticky banner
   (z-index 6 in CodeBlock.module.css); that banner itself stops below this
   toggle (rule below), so a summary's fenced code block never puts a control
   inside the toggle's band. */
.msg-compactionRow:has(.msg-compactionBody) .msg-compactionButton {
  position: sticky;
  top: 0;
  z-index: 7;
  border-radius: 0;
  background: var(--dsw-alias-bg-base);
}

/* A fenced code block in the summary pins its banner at the scrollport top,
   where this pinned toggle already sits, and the toggle's band covers the
   banner's Copy control. Stop the banner below the toggle instead, on the same
   measurement the toggle's own height uses. This rule beats CodeBlock's
   `.bannerWrap { top: 0 }` by specificity (0,2,0 against 0,1,0), not by
   declaration order: the two sheets load in their own packages. */
.msg-compactionBody :has(> [data-code-block-banner]) {
  top: var(--dsh-compaction-header-height);
}

/* Pinned, the toggle needs an opaque hover fill: the default translucent hover
   token below would let the scrolling prose show through the moment the pointer
   lands on the toggle to collapse it. */
.msg-compactionRow:has(.msg-compactionBody) .msg-compactionButton:hover {
  background: var(--dsw-alias-interactive-bg-hover-solid);
}

.msg-compactionButton:not(:disabled) {
  cursor: pointer;
}

.msg-compactionButton:not(:disabled):hover {
  background: var(--dsw-alias-interactive-bg-hover);
}

.msg-compactionLeading {
  flex: none;
  display: inline-grid;
  place-items: center;
  width: calc(16px + var(--dsh-content-font-delta, 0px));
  height: calc(16px + var(--dsh-content-font-delta, 0px));
  margin-right: 6px;
  color: var(--dsw-alias-label-secondary);
}

/* Same glyph-scaling rule as DisclosureRow's leading: the CSS edge overrides
   the svg attributes so the 14px glyphs follow the font-size delta. */
.msg-compactionLeading svg {
  width: calc(14px + var(--dsh-content-font-delta, 0px));
  height: calc(14px + var(--dsh-content-font-delta, 0px));
}

.msg-compactionContextIcon,
.msg-compactionDisclosureIcon {
  display: inline-flex;
  grid-area: 1 / 1;
  align-items: center;
  justify-content: center;
}

.msg-compactionDisclosureIcon {
  opacity: 0;
}

.msg-compactionButton:not(:disabled):hover .msg-compactionContextIcon,
.msg-compactionButton:not(:disabled):focus-visible .msg-compactionContextIcon {
  opacity: 0;
}

.msg-compactionButton:not(:disabled):hover .msg-compactionDisclosureIcon,
.msg-compactionButton:not(:disabled):focus-visible .msg-compactionDisclosureIcon {
  opacity: 1;
}

.msg-compactionTitle {
  flex: none;
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  color: var(--dsw-alias-label-primary-dimmed);
}

.msg-compactionSep {
  flex: none;
  width: 2px;
  height: 2px;
  margin: 0 8px;
  border-radius: 1px;
  background: var(--dsw-alias-label-caption);
}

.msg-compactionSummary {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  color: var(--dsw-alias-label-tertiary);
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  text-overflow: ellipsis;
  white-space: nowrap;
}

.msg-compactionBody {
  /* Indent under the title, which starts at leading (16 + delta) + gap 6. */
  padding: 4px 0 4px calc(22px + var(--dsh-content-font-delta, 0px));
  color: var(--dsw-alias-label-tertiary);
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
}

.msg-retryRow {
  color: var(--dsw-alias-label-tertiary);
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(20px + var(--dsh-content-font-delta-secondary, 0px));
}

.msg-retrySummary {
  display: inline-flex;
  align-items: center;
  width: fit-content;
  padding: 2px 0;
  gap: 7px;
  border-radius: var(--dsw-radius-sm);
  color: inherit;
  cursor: pointer;
  list-style: none;
  user-select: none;
}

.msg-retrySummary::-webkit-details-marker {
  display: none;
}

.msg-retrySummary::after {
  width: 6px;
  height: 6px;
  border-right: 1.5px solid currentcolor;
  border-bottom: 1.5px solid currentcolor;
  content: '';
  opacity: 0.8;
  transform: rotate(-45deg);
  transition: transform 120ms ease;
}

.msg-retrySummary:hover {
  color: var(--dsw-alias-label-secondary);
}

.msg-retrySummary:focus-visible {
  outline: 1.5px solid var(--dsw-focus-ring-color, var(--dsw-alias-state-business-primary));
  outline-offset: 2px;
}

.msg-retryText {
  color: inherit;
}

.msg-retryRow[data-active] .msg-retryText {
  background:
    linear-gradient(
      90deg,
      var(--dsw-alias-label-tertiary) 0%,
      var(--dsw-alias-label-tertiary) 40%,
      var(--dsw-alias-label-secondary) 50%,
      var(--dsw-alias-label-tertiary) 60%,
      var(--dsw-alias-label-tertiary) 100%
    );
  background-position: 100% 50%;
  background-size: 200% 100%;
  background-clip: text;
  color: transparent;
  animation: retry-shimmer 1.6s ease-in-out infinite;
}

.msg-retryRow[open] .msg-retrySummary::after {
  transform: rotate(45deg);
}

.msg-retryDetails {
  display: grid;
  gap: 2px;
  margin-top: 3px;
  padding-left: 14px;
  overflow-wrap: anywhere;
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(18px + var(--dsh-content-font-delta-secondary, 0px));
}

.msg-retryDetailLabel {
  color: var(--dsw-alias-label-secondary);
}

.msg-turnErrorRow {
  display: grid;
  grid-template-columns: 10px minmax(0, 1fr) auto;
  gap: 8px;
  align-items: start;
  padding: 2px 0;
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(20px + var(--dsh-content-font-delta-secondary, 0px));
}

.msg-turnErrorDot {
  margin-top: 5px;
}

.msg-turnErrorCopy {
  min-width: 0;
  overflow-wrap: anywhere;
}

.msg-turnErrorTitle {
  margin-right: 6px;
  color: var(--dsw-alias-state-error-primary);
  font-weight: 600;
}

.msg-turnErrorMessage {
  color: var(--dsw-alias-label-secondary);
}

.msg-turnErrorCode {
  color: var(--dsw-alias-label-tertiary);
  font: var(--dsw-font-markdown-code-block-small);
}

.msg-maxTokensTitle {
  margin-right: 6px;
  color: var(--dsw-alias-state-warn-primary);
  font-weight: 600;
}

@keyframes retry-shimmer {
  from {
    background-position: 100% 50%;
  }

  to {
    background-position: 0 50%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .msg-retryRow[data-active] .msg-retryText {
    background: none;
    color: inherit;
    animation: none;
  }
}

.msg-attachmentRow {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  max-width: 100%;
  gap: 8px;
}

.msg-fileCard {
  display: inline-flex;
  flex: 0 0 240px;
  align-items: center;
  gap: 10px;
  width: 240px;
  min-height: 64px;
  padding: 8px 12px;
  border: 0.5px solid var(--dsw-alias-border-l2, rgba(0, 0, 0, 0.12));
  border-radius: var(--dsw-radius-xl);
  background: var(--dsw-specific-input-major, transparent);
  box-sizing: border-box;
}

.msg-fileIcon {
  flex: none;
  width: 28px;
  height: 28px;
}

.msg-fileContent {
  display: flex;
  flex: 1;
  flex-direction: column;
  min-width: 0;
}

.msg-fileName {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--dsw-alias-label-primary);
  font-size: 14px;
  font-weight: 500;
  line-height: 22px;
}

.msg-fileMeta {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  color: var(--dsw-alias-label-tertiary, rgba(0, 0, 0, 0.45));
  font-size: 12px;
  line-height: 15px;
}


/* Source: packages/client/ui-chat/src/client/chat/TurnProcessNodeView.module.css; CSS Module classes namespaced process- */
.process-root {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  width: 100%;
  min-width: 0;
  height: calc(33px + var(--dsh-content-font-delta, 0px));
  padding: 0 0 8px;
  border: none;
  border-bottom: 0.5px solid var(--dsw-alias-border-l2);
  background: none;
  color: var(--dsw-alias-label-tertiary);
  cursor: pointer;
  text-align: left;
  transition: color 100ms ease;
}

.process-root:disabled {
  cursor: default;
}

.process-root:not(:disabled):hover {
  color: var(--dsw-alias-label-primary);
}

.process-root:not([data-open]) {
  margin-bottom: 8px;
}

.process-chevron {
  flex: none;
  width: 14px;
  height: 14px;
  margin-left: 4px;
  color: var(--dsw-alias-label-caption);
  transition: transform 100ms ease;
}

.process-root[data-open] .process-chevron {
  transform: rotate(180deg);
}

.process-label {
  min-width: 0;
  overflow: hidden;
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  text-overflow: ellipsis;
  white-space: nowrap;
}

@media (prefers-reduced-motion: reduce) {
  .process-root,
  .process-chevron {
    transition: none;
  }
}


/* Source: packages/client/ui-chat/src/client/chat/ReasoningRow.module.css; CSS Module classes namespaced thought- */
.thought-root {
  display: flex;
  flex-direction: column;
}

.thought-root:not([data-expanded]) {
  contain: size layout;
  height: calc(24px + var(--dsh-content-font-delta, 0px));
}

.thought-row {
  position: relative;
  overflow: hidden;
}

/* The uncapped body scrolls with the conversation; keep its collapse toggle
   reachable. Compact Markdown code banners stay in flow below this header. */
.thought-root[data-expanded] [data-open] [data-disclosure-row] {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--dsw-alias-bg-base);
}

.thought-root[data-state='running'] .thought-row::after {
  content: '';
  position: absolute;
  inset-block: 0;
  left: 0;
  width: 300px;
  background: linear-gradient(
    90deg,
    transparent 0%,
    color-mix(in srgb, var(--dsw-alias-bg-base) 60%, transparent) 55%,
    transparent 100%
  );
  animation: dsh-reasoning-row-sweep 2.6s ease-out infinite;
  pointer-events: none;
}

@keyframes dsh-reasoning-row-sweep {
  0% { left: -300px; }
  90%, 100% { left: 100%; }
}

.thought-leading {
  flex-shrink: 0;
}

.thought-chevron {
  color: var(--dsw-alias-label-secondary);
}

.thought-title {
  font-weight: 400;
}

.thought-separator {
  flex: none;
  width: 2px;
  height: 2px;
  margin: 0 8px;
  border-radius: 1px;
  background: var(--dsw-alias-label-caption);
}

/* Think text reads the secondary tier — one step under the body size
   (setting −1 at ≤14, setting −2 above), shared with every flow-row title
   and summary. */
.thought-summary {
  min-width: 0;
  overflow: hidden;
  flex: 1 1 auto;
  color: var(--dsw-alias-label-tertiary);
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(20px + var(--dsh-content-font-delta-secondary, 0px));
  white-space: nowrap;
}

.thought-summaryText {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
}

.thought-summary[data-streaming] {
  mask-image: linear-gradient(to right, black calc(100% - 48px), transparent);
}

.thought-summary[data-streaming] .thought-summaryText {
  overflow: visible;
  text-overflow: clip;
}

.thought-root:not([data-preview]) .thought-separator,
.thought-root:not([data-preview]) .thought-summary {
  display: none;
}

.thought-thinkBody {
  /* Indent under the title, which starts at leading (16 + delta) + gap 6. */
  padding: 4px 0 4px calc(22px + var(--dsh-content-font-delta, 0px));
  min-width: 0;
}

@media (prefers-reduced-motion: reduce) {
  .thought-root[data-state='running'] .thought-row::after {
    animation: none;
  }
}


/* Source: packages/client/ui-chat/src/client/chat/AssistantMarkdown.module.css; CSS Module classes namespaced markdown- */
/* Assistant flow body: full-width narration (figma 16/28 scaled 0.875 → 14/24
   with the markdown token ladder), block gap 16. The Settings font-size
   preference rides the body-published axis: size follows
   --dsh-content-font-size and the line height keeps the 10px leading via the
   shared px delta. IconActions sit below the body with an explicit 16px top
   margin (figma 43:32997) — separate from the body's internal gap so the
   footer spacing stays fixed when the body is a single block. */

.markdown-root {
  display: flex;
  flex-direction: column;
  font-size: var(--dsh-content-font-size, 14px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  color: var(--dsw-alias-label-primary);
}

.markdown-body {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Wide markdown tables (the renderer's ≥4-column md-table-wide hook) span
   the whole transcript width instead of clipping at the 748px message
   column, while the table content keeps starting at its normal x (the lead
   padding compensates the negative margin) — deepsuite chat TableWrapper
   parity, with 100cqw (the ChatView scroll container) standing in for its
   JS-measured --dsl-virtual-list-width. `--dsh-table-spare` clamps to zero
   when the transcript is narrower than the message column, so narrow
   viewports keep the plain in-column scroll with no sideways shift.
   Percentages resolve against the wrapper's containing block, so a table
   indented inside a list still reaches the same transcript edges. */
.markdown-body .md-table-wide {
  --dsh-table-spare: max(0px, calc((100cqw - var(--dsh-chat-content-width)) / 2));
  --dsh-table-lead: calc(var(--dsh-table-spare) + min(var(--dsh-chat-content-width), 100cqw) - 100%);
  box-sizing: border-box;
  width: calc(100% + var(--dsh-table-lead) + var(--dsh-table-spare));
  /* The base .tableScroll caps at the column (max-width: 100%); the breakout
     is exactly the case that must exceed it. */
  max-width: none;
  margin-left: calc(-1 * var(--dsh-table-lead));
  padding-left: var(--dsh-table-lead);
}

/* Only the painted table outranks Conversation's z-index 0 width handle. The
   full-width scroll wrapper and its transparent alignment padding stay below,
   so a fitting four-column table does not disable the surrounding gutter. */
.markdown-body .md-table-wide > table {
  position: relative;
  z-index: 1;
}

/* hidden="until-found" keeps a zero-height reasoning box in flex layout.
   Cancel the one gap that box would otherwise leave before the visible reply;
   visible Assistant blocks retain the ordinary 16px rhythm. */
.markdown-body > [data-turn-process-inline][hidden] {
  margin-bottom: -16px;
}

/* Interrupted-turn terminal marker: quiet inline tag, no animation. Fixed
   size like the small/code token variants — 11px is dense secondary text
   that would fall to an illegible 9px at the 12px floor. */
.markdown-stopped {
  align-self: flex-start;
  padding: 0 6px;
  border-radius: var(--dsw-radius-sm);
  background: var(--dsw-alias-interactive-bg-hover);
  color: var(--dsw-alias-label-tertiary);
  font-size: 11px;
  line-height: 18px;
}

/* Finalized footer offset (figma 43:32997); chrome lives in MessageIconActions. */
.markdown-actions {
  margin-top: 16px;
  /* Optical align with the 28px action hit targets. */
  margin-left: -6px;
}


/* Source: packages/client/ui-chat/src/client/chat/ChatGroupSeat.module.css; CSS Module classes namespaced group- */
.group-root {
  min-width: 0;
}

.group-title {
  display: flex;
  max-width: 100%;
  align-items: center;
  gap: 6px;
  padding: 0;
  border: 0;
  background: none;
  color: var(--dsw-alias-label-secondary);
  font: inherit;
  font-size: var(--dsh-content-font-size, 14px);
  text-align: left;
  cursor: pointer;
  transition: color 100ms ease;
}

.group-title:hover {
  color: var(--dsw-alias-label-primary);
}

.group-leading {
  position: relative;
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 16px;
  color: var(--dsw-alias-label-tertiary);
}

.group-activityIcon,
.group-chevron {
  position: absolute;
  inset: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  transition: opacity 100ms ease;
}

.group-activityIcon {
  opacity: 1;
}

.group-chevron {
  opacity: 0;
}

.group-title:is(:hover, :focus-visible) .group-activityIcon {
  opacity: 0;
}

.group-title:is(:hover, :focus-visible) .group-chevron {
  opacity: 1;
}

.group-title[aria-expanded="true"] .group-activityIcon {
  opacity: 0;
}

.group-title[aria-expanded="true"] .group-chevron {
  opacity: 1;
}

.group-title[aria-expanded="true"] {
  padding-bottom: 16px;
}

.group-body {
  --dsh-chat-flow-gap: 8px;
  max-height: min(400px, 50cqh);
  overflow-y: auto;
  overscroll-behavior-y: auto;
  scrollbar-gutter: stable;
}

.group-label {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.group-fadeTop {
  mask-image: linear-gradient(to bottom, transparent 0, #000 24px, #000 100%);
}

.group-fadeBottom {
  mask-image: linear-gradient(to bottom, #000 0, #000 calc(100% - 24px), transparent 100%);
}

.group-fadeTop.group-fadeBottom {
  mask-image: linear-gradient(
    to bottom,
    transparent 0,
    #000 24px,
    #000 calc(100% - 24px),
    transparent 100%
  );
}

@media (prefers-reduced-motion: reduce) {
  .group-title,
  .group-activityIcon,
  .group-chevron {
    transition: none;
  }
}

.group-content {
  display: flex;
  flex-direction: column;
}
.group-content > * { flex-shrink: 0; }
.group-content > :not([hidden]):not(:empty) ~ :not([hidden]):not(:empty) {
  margin-top: var(--dsh-chat-flow-gap, 8px);
}
.group-expandedBody {
  --dsh-chat-flow-gap: 16px;
  max-height: none;
  overflow: visible;
  scrollbar-gutter: auto;
}


/* Source: packages/client/ui-user-questions/src/client/QuestionComposer.module.css; CSS Module classes namespaced question- */
/* The takeover seats where the input card sits, centered on the InputBar
   axis at the shared content width (input card - 32): sides = clearance +
   16px so the relation also holds on narrow viewports. */
.question-frame {
  display: flex;
  justify-content: center;
  padding: 6px calc(var(--dsh-composer-side-clearance) + 16px) 10px;
}

/* Figma Input 973:36348 body over the 1019:36938 header: no banner strip —
   the card keeps zero padding and sections carry their own insets. */
.question-card {
  display: flex;
  flex-direction: column;
  width: 100%;
  max-width: var(--dsh-chat-content-width);
  /* Composer seat sits in a fixed-height conversation column (overflow
     hidden): cap the card against the viewport and scroll the option list
     so header and footer actions stay reachable on long batches. */
  max-height: min(60cqh, 520px);
  padding: 0 0 10px;
  border: 0;
  --dsw-elevation-stroke-color: var(--dsw-alias-border-l2-darkmode-thin);
  border-radius: var(--dsw-radius-xl);
  background: var(--dsw-specific-input-major);
  box-shadow: var(--dsw-elevation-panel);
  color: var(--dsw-alias-label-primary);
  overflow: hidden;
  /* Elevated surface in dark, same as the menus: the body inside scrolls
     once the card hits the cap above, so the thumb takes the l2 pair. Declared
     on the card because the elevation belongs to the surface, and the custom
     properties inherit down to `.body` (see ui-theme styles/scrollbar.css
     for the rebinding contract). */
  --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2);
  --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2);
}

.question-card,
.question-card * {
  box-sizing: border-box;
}

/* Collapsed to the header strip: drop the height cap and the inner scroll
   seat so the card hugs the title row, freeing the viewport for the
   conversation above while the question stays pending. */
.question-cardMinimized {
  max-height: none;
}

/* The header strip is the whole card when collapsed: the title row needs
   bottom padding once the body that normally carries it is hidden. */
.question-cardMinimized .question-header {
  padding-bottom: 14px;
}

/* Header button group: minimize sits next to the close action, both on the
   same 24px icon-button grid. */
.question-headerActions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

/* Figma 1019:36938 header, user-tuned: heading block left, close right; the
   pager sits in the footer to balance the card. */
.question-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: 16px;
  flex-shrink: 0;
  padding: 20px 16px 0 24px;
}

.question-headingBlock {
  min-width: 0;
}

.question-eyebrow {
  /* Eyebrow-to-title gap widened from the figma 2px (user-tuned). */
  margin-bottom: 5px;
  color: var(--dsw-alias-label-tertiary);
  font-size: 11px;
  line-height: 16px;
}

.question-title {
  margin: 0;
  font-size: 16px;
  line-height: 22px;
  font-weight: 500;
}

.question-detail {
  margin: 0 2px 8px;
}

.question-footerActions {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-shrink: 0;
}

.question-pager {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
}

.question-progress {
  padding: 0 4px;
  color: var(--dsw-alias-label-secondary);
  font-size: 14px;
  line-height: 24px;
  font-weight: 500;
  white-space: nowrap;
  /* Narrow the plain spaces around the slash without touching glyph tracking. */
  word-spacing: -2px;
}

.question-iconButton {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
  padding: 0;
  border: none;
  border-radius: 999px;
  corner-shape: round;
  background: transparent;
  color: var(--dsw-alias-label-tertiary);
  cursor: pointer;
}

.question-iconButton:hover:not(:disabled) {
  background: var(--dsw-alias-interactive-bg-hover);
  color: var(--dsw-alias-label-primary);
}

.question-iconButton:disabled {
  color: var(--dsw-alias-label-dimmed);
  cursor: default;
}

.question-body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
}

.question-options {
  display: flex;
  flex-direction: column;
  gap: 1px;
  margin: 8px 0 0;
  padding: 4px 12px;
}

.question-option {
  display: flex;
  /* flex-start, not center: with a wrapped description the indicator must
     stay on the FIRST line (centering drifts it down the taller copy block).
     The 8px padding makes a single-line row 40px exactly, so nothing reads
     as top-heavy; .number/.checkbox re-center against the first line box. */
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  min-height: 40px;
  /* Rows are the scroll content, never the slack absorber: a shrinkable row
     collapses to min-height while its wrapped copy keeps the taller
     intrinsic height, and centered content then paints outside the row box —
     over the title and the next row. Overflow belongs to .options. */
  flex-shrink: 0;
  padding: 8px 12px 8px 8px;
  border: 1px solid transparent;
  border-radius: var(--dsw-radius-md);
  background: transparent;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease;
}

.question-option:hover:not(:disabled),
.question-optionSelected {
  background: var(--dsw-alias-interactive-bg-hover);
}

.question-optionSelected {
  border-color: var(--dsw-alias-border-l2);
}

.question-option:disabled {
  cursor: default;
}

/* Leading indicator (20×20): single-select shows the option
   number, multi-select swaps in a checkbox; the custom-answer row follows —
   its checkbox mirrors the typed draft (styling only, exclusivity holds). */
.question-number {
  display: grid;
  place-items: center;
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  /* (24px first-line box − 20px indicator) / 2: centers the indicator against
     the first text line under the row's flex-start alignment. */
  margin-top: 2px;
  border-radius: var(--dsw-radius-xs);
  background: var(--dsw-alias-bg-overlay);
  color: var(--dsw-alias-label-secondary);
  font-size: 12px;
  font-weight: 500;
  line-height: 18px;
}

/* Multi-select box (figma 1055:41594, user-tuned down to 14×14): a radius-4
   box centered in the 20px indicator seat; the box itself is the ::before
   layer so the check icon stacks over it in the same grid cell. */
.question-checkbox {
  display: grid;
  place-items: center;
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  /* Same first-line centering as .number under flex-start alignment. */
  margin-top: 2px;
}

.question-checkbox::before {
  content: '';
  grid-area: 1 / 1;
  width: 14px;
  height: 14px;
  border: 0.5px solid var(--dsw-alias-border-l4);
  border-radius: var(--dsw-radius-xs);
  transition: background-color 120ms ease, border-color 120ms ease;
}

.question-checkbox > svg {
  grid-area: 1 / 1;
}

/* Checked: label-primary fill with a primary-foreground check — the pair
   inverts with the theme (dark fill in light mode, light fill in dark mode). */
.question-checkboxChecked {
  color: var(--dsw-alias-label-primary-foreground);
}

.question-checkboxChecked::before {
  border-color: var(--dsw-alias-label-primary);
  background: var(--dsw-alias-label-primary);
}

.question-optionCopy {
  min-width: 0;
  flex: 1;
}

.question-optionLine {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 2px 6px;
}

.question-optionLabel {
  font-size: 14px;
  line-height: 24px;
  font-weight: 500;
}

.question-badge {
  padding: 0 4px;
  border-radius: var(--dsw-radius-xs);
  background: var(--dsw-specific-sidebar-nav-item-active-accent);
  color: var(--dsw-alias-button-info-fill);
  font-size: 11px;
  line-height: 18px;
  font-weight: 600;
}

.question-description {
  color: var(--dsw-alias-label-tertiary);
  font-size: 14px;
  line-height: 24px;
  font-weight: 400;
}

/* Custom answer row (figma 973:36427): an option-shaped row whose copy is an
   inline text input; focus or a typed draft lifts it to the selected look. */
.question-customRow {
  display: flex;
  /* Same first-line alignment as .option — the indicator seat carries the
     2px re-centering margin. */
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  min-height: 40px;
  /* Same reason as .option: the custom row is scroll content, and shrinking
     it pushes the inline input past the footer. */
  flex-shrink: 0;
  padding: 8px 12px 8px 8px;
  border: 1px solid transparent;
  border-radius: var(--dsw-radius-md);
  transition: background-color 120ms ease, border-color 120ms ease;
}

.question-customRow:hover,
.question-customRow:focus-within,
.question-customRowActive {
  background: var(--dsw-alias-interactive-bg-hover);
}

.question-customRow:focus-within,
.question-customRowActive {
  border-color: var(--dsw-alias-border-l2);
}

/* Auto-growing free-text answer (see AnswerField): mirror and textarea share
   one grid cell, the mirror sizes it, and the textarea stretches to it. The
   two layers MUST keep identical type, padding and wrapping — a mismatch
   makes the box the wrong height for the text the user is typing. */
.question-field {
  display: grid;
  min-width: 0;
  --dsh-answer-field-padding: 0;
}

.question-field > * {
  grid-area: 1 / 1;
  min-width: 0;
  padding: var(--dsh-answer-field-padding);
  font: inherit;
  font-size: 14px;
  line-height: 24px;
  white-space: pre-wrap;
  word-break: break-word;
  overflow-wrap: anywhere;
}

/* The height ruler, never painted. Growth stops at 6 lines: the card body is
   capped at 520px and still owes that budget to the title, the option rows and
   the footer actions, so a long answer scrolls in the textarea instead of
   pushing the choices it belongs to out of view.
   content-box overrides the card-wide border-box so the cap counts TEXT lines
   in both variants: under border-box the block variant's 16px of vertical
   padding eats two thirds of a line and the sixth one arrives as an 8px sliver.
   Width is unaffected — a stretched grid item's used width comes from the
   track, not from this box-sizing. */
.question-fieldMirror {
  box-sizing: content-box;
  max-height: 144px;
  overflow: hidden;
  visibility: hidden;
}

.question-fieldInput {
  resize: none;
  /* The stack's only scrollport: past the mirror's cap the field stops growing
     and this scrolls. */
  overflow-y: auto;
  border: none;
  outline: none;
  background: transparent;
  color: var(--dsw-alias-label-primary);
  caret-color: var(--dsw-alias-state-business-primary);
}

.question-fieldInput::placeholder {
  color: var(--dsw-alias-label-caption);
}

/* Inline variant: the custom row's copy column, borrowing the row's chrome. */
.question-customInline {
  flex: 1;
}

/* Optionless question: the free-form answer is the whole body, so it carries
   its own frame. The 12px side margins add to the .options 12px padding so both
   edges align with the title's 24px inset; two lines are reserved before the
   answer starts growing. */
.question-customBlock {
  min-height: 64px;
  flex-shrink: 0;
  margin: 0 12px;
  border: 0.5px solid var(--dsw-alias-border-l4);
  border-radius: var(--dsw-radius-lg);
  background: var(--dsw-alias-bg-module-platform);
  --dsh-answer-field-padding: 8px 12px;
}

.question-customBlock:focus-within {
  border-color: var(--dsw-alias-state-business-primary);
}

.question-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-shrink: 0;
  margin-top: 12px;
  padding: 0 10px 0 18px;
}

.question-feedback {
  flex: 1;
  min-height: 16px;
  color: var(--dsw-alias-state-error-primary);
  font-size: 11px;
  line-height: 16px;
  text-align: right;
}

@container dsh-surface (max-width: 720px) {
  .question-card {
    border-radius: var(--dsw-radius-xl);
  }

  .question-header {
    padding: 10px 12px 0 18px;
  }

  .question-options {
    padding: 4px 8px;
  }

  .question-title {
    font-size: 15px;
    line-height: 21px;
  }

  .question-option,
  .question-customRow {
    padding: 8px 6px;
  }

  .question-footer {
    align-items: flex-end;
    padding: 0 10px;
  }

  .question-footerActions {
    flex-shrink: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .question-option,
  .question-customRow {
    transition: none;
  }
}


/* Source: packages/client/ui-primitives/src/DisclosureRow.module.css; CSS Module classes namespaced disclosure- */
/* Shared disclosure header: [16px leading] gap 6 [title 13/24] at the default
   size. The Settings font-size preference moves the row through the
   body-published axis: title size follows the secondary tier
   (--dsh-content-font-size-secondary: one step under the body — setting −1 at
   ≤14, setting −2 above), and the row height, leading box, and glyph edge
   shift by the body px delta so the icon keeps its optical share of the
   line. */

.disclosure-root {
  display: flex;
  flex-direction: column;
  width: 100%;
  min-width: 0;
}

.disclosure-row {
  position: relative;
  overflow: hidden;
  display: flex;
  align-items: center;
  height: calc(24px + var(--dsh-content-font-delta, 0px));
  min-width: 0;
}

.disclosure-row[data-expandable] {
  cursor: pointer;
}

.disclosure-leading {
  position: relative;
  flex: none;
  width: calc(16px + var(--dsh-content-font-delta, 0px));
  height: calc(16px + var(--dsh-content-font-delta, 0px));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-right: 6px;
  padding: 0;
  border: none;
  background: none;
  color: var(--dsw-alias-label-tertiary);
}

/* Flow-row glyphs render at 14px inside the 16px box; the CSS edge overrides
   each svg's own width/height attributes so every registered icon scales
   without a per-callsite size prop. StateDot (its svg carries data-state)
   stays at its fixed figma size — it is a status mark, not text furniture. */
.disclosure-leading svg:not([data-state]) {
  width: calc(14px + var(--dsh-content-font-delta, 0px));
  height: calc(14px + var(--dsh-content-font-delta, 0px));
}

button.disclosure-leading {
  cursor: pointer;
}

.disclosure-iconIdle {
  display: inline-flex;
  opacity: 1;
  transition: opacity 100ms ease;
}

.disclosure-chevronHover {
  position: absolute;
  inset: 0;
  margin: auto;
  opacity: 0;
  transition: opacity 100ms ease;
}

.disclosure-row:hover .disclosure-iconIdle {
  opacity: 0;
}

.disclosure-row:hover .disclosure-chevronHover {
  opacity: 1;
}

.disclosure-title {
  flex: none;
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  color: var(--dsw-alias-label-secondary);
}


/* Source: packages/client/ui-primitives/src/Button.module.css; CSS Module classes namespaced button- */
/* Button sizes share the global control-radius scale. */
.button-button {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  border: none;
  border-radius: var(--dsw-radius-md);
  cursor: pointer;
  font-size: 14px;
  line-height: 22px;
  color: var(--dsw-alias-label-primary);
  background: transparent;
  padding: 0 14px;
}

.button-button:disabled {
  cursor: not-allowed;
  opacity: 0.4;
}

.button-md {
  height: 36px;
}

/* Compact controls retain their dimensions across filled and outlined variants. */
.button-sm {
  height: 28px;
  font-size: 12px;
  line-height: 18px;
  padding: 0 10px;
  border-radius: var(--dsw-radius-sm);
}

.button-primary {
  background: var(--dsw-alias-button-primary-fill);
  color: var(--dsw-alias-label-primary-foreground);
}

.button-primary:hover:not(:disabled) {
  background: var(--dsw-alias-button-primary-hover);
}

.button-ghost:hover:not(:disabled) {
  background: var(--dsw-alias-interactive-bg-hover);
}

.button-ghost:active:not(:disabled) {
  background: var(--dsw-alias-interactive-bg-active);
}

/* Outlined actions use the same neutral stroke as settings links. */
.button-outline {
  border: 0.5px solid var(--dsw-alias-border-l3);
  background: transparent;
}

.button-outline:hover:not(:disabled) {
  background: var(--dsw-alias-interactive-bg-hover);
}

.button-toolbar {
  background: var(--dsw-alias-button-tool-bar-fill);
}

.button-toolbar:hover:not(:disabled) {
  background: var(--dsw-alias-button-tool-bar-hover);
}

.button-icon {
  display: inline-flex;
  width: 16px;
  height: 16px;
  align-items: center;
  justify-content: center;
}


/* Source: packages/client/ui-primitives/src/TextShimmer.module.css; CSS Module classes namespaced shimmer- */
.shimmer-root[data-text-shimmer] {
  background-image: linear-gradient(
    90deg,
    currentColor calc(50% - var(--dsh-text-shimmer-spread)),
    color-mix(in oklab, currentColor 50%, transparent),
    currentColor calc(50% + var(--dsh-text-shimmer-spread))
  );
  background-position: 100% center;
  background-repeat: no-repeat;
  background-size: 250% 100%;
  background-clip: text;
  -webkit-background-clip: text;
  -webkit-text-fill-color: transparent;
  animation: dsh-text-shimmer 1.5s cubic-bezier(0.33, 0, 0.67, 1) infinite;
}

@keyframes dsh-text-shimmer {
  66.6667%, 100% { background-position: 0% center; }
}

@media (prefers-reduced-motion: reduce) {
  .shimmer-root[data-text-shimmer] {
    background-image: none;
    -webkit-text-fill-color: currentColor;
    animation: none;
  }
}


/* Source: packages/client/ui-tool/src/client/tool/components/ToolRow.module.css; CSS Module classes namespaced tool- */
/* Tool summary row (figma 122:9479): 24px single line at the default size —
   [16 leading] gap6 [title 13/24] gap8 [2x2 dot] gap8 [summary FILL truncate].
   The Settings font-size preference rides the body-published axis: the shared
   DisclosureRow chrome scales the row height and leading glyph by the body px
   delta; the title and the summary texts here read the secondary tier
   (--dsh-content-font-size-secondary: one step under the body — setting −1 at
   ≤14, setting −2 above), matching think text. */

.tool-root {
  display: flex;
  flex-direction: column;
}

.tool-leading {
  flex-shrink: 0;
}

/* Cordis lifecycle tools retain their generic row mechanics while carrying a
   shared product accent and tool-owned action title. */
.tool-root[data-tool^='cordis_'] .tool-leading,
.tool-root[data-tool^='cordis_'] .tool-title {
  color: var(--dsw-alias-state-business-primary);
}

.tool-root[data-tool^='cordis_'] .tool-title {
  font-weight: 500;
}

.tool-root[data-tool^='cordis_'] .tool-sep {
  background: var(--dsw-alias-state-business-primary);
}

.tool-chevron {
  color: var(--dsw-alias-label-secondary);
}

.tool-title {
  font-weight: 400;
  transition: color 100ms ease;
}

.tool-sep {
  flex: none;
  width: 2px;
  height: 2px;
  border-radius: 1px;
  margin: 0 8px;
  background: var(--dsw-alias-label-caption);
}

.tool-summary {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  color: var(--dsw-alias-label-tertiary);
  transition: color 100ms ease;
}

/* Trailing summary fragment kept out of .summary's ellipsis, for a count whose
   whole value is that it survives a narrow row (the todo row's parallel-active
   `+n`). Repeats .summary's type because it sits beside that text, and its
   `nowrap` too: `flex: none` stops the box shrinking but not the text wrapping,
   which would break the one-line row in the narrow case the slot exists for. */
.tool-summarySuffix {
  flex: none;
  margin-left: 4px;
  white-space: nowrap;
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  color: var(--dsw-alias-label-tertiary);
  transition: color 100ms ease;
}

.tool-row:hover .tool-title,
.tool-row:hover .tool-summary:not(.tool-errorSummary):not(.tool-stoppedSummary),
.tool-row:hover .tool-summarySuffix {
  color: var(--dsw-alias-label-primary);
}

/* Diff-row +/- totals: the code font, matching the diff body the numbers
   summarize; a wider gap keeps the digits from reading as part of the path.
   Two px under the secondary tier (still riding the axis): mono digits read
   optically larger than the sans path at the same size. Caption, one step
   dimmer than the suffix's tertiary, so the digits stay behind the path. The
   half-pixel nudge closes the baseline gap the size difference leaves under
   the row's box-centering (a transform, so flex layout is untouched). */
.tool-diffStat {
  margin-left: 10px;
  font-family: var(--ds-font-family-code);
  font-size: calc(var(--dsh-content-font-size-secondary, 13px) - 2px);
  color: var(--dsw-alias-label-caption);
  transform: translateY(0.5px);
}

/* File-tool path: same type as .summary, with a persistent link affordance.
   Dotted dimmed underline: visible enough to say "clickable", light enough
   that a long path doesn't read as one heavy rule under the row. Shrink-to-fit
   (flex 0): the click target ends where the path text ends — the row's empty
   remainder stays the expand/collapse toggle. */
.tool-fileLink {
  flex: 0 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  text-align: left;
  font-size: var(--dsh-content-font-size-secondary, 13px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
  color: var(--dsw-alias-label-secondary);
  text-decoration: underline dotted;
  text-decoration-color: var(--dsw-alias-label-tertiary);
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
  cursor: pointer;
  transition: color 100ms ease;
}

.tool-row:hover .tool-fileLink,
.tool-fileLink:hover {
  color: var(--dsw-alias-label-primary);
  text-decoration-color: currentColor;
}

/* Error row's collapsed summary: the failure's first line in the error color. */
.tool-errorSummary {
  color: var(--dsw-alias-state-error-primary);
}

/* Interrupted rows retain their business glyph and replace the summary with a visible warning. */
.tool-stoppedSummary {
  color: var(--dsw-alias-state-warn-label);
}

/* Expanded body + Inspect pill wrapper (sibling of .row: clicks never toggle). */
.tool-bodyWrap {
  display: flex;
  flex-direction: column;
}

/* Hover-revealed jump to the trajectory record: a small pill in real flow
   under the expanded body's bottom-left corner (it reserves its line, so
   revealing never shifts layout); revealed by hovering anywhere on the tool
   call — title row included — or by keyboard focus. */
.tool-inspectButton {
  display: inline-flex;
  align-self: flex-start;
  align-items: center;
  gap: 4px;
  margin: 4px 0 2px 4px;
  padding: 2px 8px;
  border: 0.5px solid var(--dsw-alias-border-l3);
  border-radius: 999px;
  corner-shape: round;
  /* Base background, not bg-overlay: the overlay token is a raised dark
     surface and reads too heavy for a quiet in-flow affordance. */
  background: var(--dsw-alias-bg-base);
  color: var(--dsw-alias-label-secondary);
  font-size: 11px;
  line-height: 16px;
  cursor: pointer;
  opacity: 0;
  transition: opacity 100ms ease;
}

.tool-root:hover .tool-inspectButton,
.tool-inspectButton:focus-visible {
  opacity: 1;
}

.tool-detailsBodyWrap {
  position: relative;
}

.tool-detailsBodyWrap .tool-inspectButton {
  position: absolute;
  top: 12px;
  right: 12px;
  margin: 0;
}

/* Solid hover fill (a translucent token would let content bleed through). */
.tool-inspectButton:hover {
  background: var(--dsw-alias-interactive-bg-hover-solid);
  color: var(--dsw-alias-label-primary);
}

/* Expanded-body scroll wrapper for the run_code CodeBlock; the IN/OUT card
   and the terminal card scroll INSIDE their own surface instead, so the
   scrollbar sits within the rounded card. */
.tool-bodyScroll {
  max-height: 260px;
  overflow-y: auto;
}

/* Expanded input/output card (figma 1249:35657): the code-block surface and
   radius from the TerminalBlock/CodeBlock family. The card itself is a plain
   column — the padding and the IN/OUT gutter-label grid live on each section
   so the divider spans the full card width and each section scrolls alone. */
.tool-ioCard {
  display: flex;
  flex-direction: column;
  margin: 4px 0 4px 4px;
  border: 0.5px solid var(--dsw-alias-border-l1);
  border-radius: var(--dsw-radius-lg);
  background: var(--dsw-alias-markdown-code-block);
  font: var(--dsw-font-markdown-code-block-small);
}

/* One card section (IN or OUT): the gutter-label grid, capped and scrolling
   independently so a long input never buries a short output (and vice versa). */
.tool-ioSection {
  display: grid;
  grid-template-columns: max-content 1fr;
  column-gap: 14px;
  align-items: baseline;
  padding: 12px 16px;
  max-height: 150px;
  overflow-y: auto;
}

/* Card-internal scrollbar: a 2px transparent border clips the thumb inward so
   it floats off the rounded card edge instead of hugging it (the terminal
   card's own output scroller carries the same treatment in TerminalBlock). */
.tool-ioSection::-webkit-scrollbar-thumb {
  border: 2px solid transparent;
  background-clip: padding-box;
  border-radius: var(--dsw-radius-sm);
}

/* Track end-margins keep the thumb's travel out of the rounded corners. */
.tool-ioSection::-webkit-scrollbar-track {
  margin: 6px 0;
}

/* Caption (not tertiary): one step dimmer than the payload text so the
   gutter labels read as labels, not as part of the content. Sticky against
   the section's own scroll so the label stays readable while its payload
   scrolls underneath (top 0 = the section's padding edge inside the
   scrollport; start-aligned because sticky needs a block-start anchor). */
.tool-ioLabel {
  position: sticky;
  top: 0;
  align-self: start;
  color: var(--dsw-alias-label-caption);
}

/* l2 hairline between the IN and OUT sections, spanning the full card width
   (it sits between the padded sections, not inside their grid). */
.tool-ioDivider {
  flex: none;
  height: 0.5px;
  background: var(--dsw-alias-border-l2);
}

.tool-ioText {
  min-width: 0;
  white-space: pre-wrap;
  word-break: break-word;
  color: var(--dsw-alias-label-secondary);
}

/* A failed call's OUT text shares the collapsed summary's error color. */
.tool-ioText[data-error] {
  color: var(--dsw-alias-state-error-primary);
}

/* The block-shaped expanded bodies: the code variant's run_code program
   through CodeBlock (shiki-highlighted TypeScript), a terminal card's command
   output through TerminalBlock, a diff card through DiffBlock, a read card's
   line-numbered window through ReadBlock, a search card's grouped matches or
   path list through SearchBlock, and a web card's citation/source list through
   WebBlock. All are drawn by the shared primitive, so only the row's
   indentation is this file's concern — the margin also replaces each
   primitive's own standalone vertical spacing with the flow's row rhythm. */
.tool-codeBody,
.tool-terminalBody,
.tool-diffBody,
.tool-readBody,
.tool-imageBody,
.tool-searchBody,
.tool-webBody {
  margin: 4px 0 4px 4px;
}

/* The recovery footer for a capped search: the result text (its `Full … stored
   at …` locator) below the card in the muted tone, since the card holds only the
   retained rows. Same column indent as the card body. */
.tool-searchRecovery {
  margin: 4px 0 4px 4px;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font: var(--dsw-font-xs-13);
  color: var(--dsw-alias-label-tertiary);
}

/* The image card's in-card label: the view's replacement title, else the
   shortened path — the same role ReadBlock's own label plays, so the presentation
   contract's replacement-title rule is honoured here too. */
.tool-imageLabel {
  margin-bottom: 4px;
  overflow-wrap: anywhere;
  font: var(--dsw-font-sm-13);
  color: var(--dsw-alias-label-secondary);
}

/* The image card's own result text (media type, dimensions, byte size) under the
   gallery, in the same muted tone the search recovery footer uses. Always
   rendered: the attachment presentation slot is optional, so when nothing
   occupies it the gallery is empty and this line is the only evidence an image
   was returned. The enclosing .imageBody already carries the row indent. */
.tool-imageMeta {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font: var(--dsw-font-xs-13);
  color: var(--dsw-alias-label-tertiary);
}

/* The terminal card scrolls its OUTPUT inside its own surface (same l1
   hairline as the IN/OUT card): the banner stays pinned and the scrollbar
   never rides over it. 224px = the 260px card cap minus the ~36px banner. */
.tool-terminalBody {
  --dsl-terminal-font: var(--dsw-font-markdown-code-block-small);
  --dsl-terminal-line-height: 18px;
  --dsl-terminal-output-max-height: 224px;
  border: 0.5px solid var(--dsw-alias-border-l1);
}

/* Visually hidden run-state label for assistive technology: the business icon
   and animated text treatment do not name the state, so this text carries the
   running/failed/interrupted state to a screen reader. */
.tool-visuallyHidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}


/* Source: packages/client/ui-tool/src/client/tool/components/AskQuestionCard.module.css; CSS Module classes namespaced answer- */
.answer-card {
  display: flex;
  flex-direction: column;
  gap: 16px;
  max-height: 360px;
  margin: 4px 0 4px 4px;
  padding: 16px 20px;
  overflow-y: auto;
  border: 0.5px solid var(--dsw-alias-border-l1);
  border-radius: var(--dsw-radius-lg);
  background: var(--dsw-alias-bg-base);
}

.answer-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 0;
}

.answer-question,
.answer-answer {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: var(--dsh-content-font-size, 14px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
}

.answer-question {
  color: var(--dsw-alias-label-tertiary);
}

.answer-answer {
  color: var(--dsw-alias-label-primary);
}

.answer-answerLine {
  display: block;
}

.answer-skipped {
  color: var(--dsw-alias-label-tertiary);
}

.answer-verdict {
  margin: 0;
  color: var(--dsw-alias-label-primary);
  font-size: var(--dsh-content-font-size, 14px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
}

.answer-questionList {
  display: flex;
  flex-direction: column;
  gap: 8px;
  margin: 0;
  padding-left: 20px;
}

.answer-unansweredQuestion {
  color: var(--dsw-alias-label-tertiary);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-size: var(--dsh-content-font-size, 14px);
  line-height: calc(24px + var(--dsh-content-font-delta, 0px));
}


/* Source: packages/client/ui-message-feedback/src/client/MessageFeedbackActions.module.css; CSS Module classes namespaced feedback- */
.feedback-action {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Rides the Settings font-size axis like the host row's own actions
     (ui-chat MessageIconActions), so slot-injected buttons match their
     siblings at every size. */
  width: calc(28px + var(--dsh-content-font-delta, 0px));
  height: calc(28px + var(--dsh-content-font-delta, 0px));
  padding: 6px;
  border: none;
  border-radius: var(--dsw-radius-sm);
  background: transparent;
  color: var(--dsw-alias-label-tertiary);
  cursor: pointer;
}

/* The 15px glyphs follow the same px delta as the text they serve; the CSS
   edge overrides each svg's own width/height attributes. */
.feedback-action svg {
  width: calc(15px + var(--dsh-content-font-delta, 0px));
  height: calc(15px + var(--dsh-content-font-delta, 0px));
}

.feedback-action:hover {
  background: var(--dsw-alias-interactive-bg-hover);
  color: var(--dsw-alias-label-secondary);
}

.feedback-action:disabled {
  cursor: default;
  opacity: 0.4;
}

/* A recorded rating stays legible without hover, so the signal survives a
   pointer leaving the row. */
.feedback-action[data-active] {
  color: var(--dsw-alias-label-tertiary);
}

.feedback-failure {
  padding-left: 4px;
  color: var(--dsw-alias-label-tertiary);
  font-size: 13px;
  line-height: 20px;
}
/* demo-section:dsh-surface:end */

/* demo-section:assistant-overrides:start */
/* Host reset, timeline adapter and requested demo variants. Original component
   declarations remain in the generated DSH stylesheet. */
:host { overflow: hidden; font: 14px/1.5 var(--dsw-font-family); color: var(--dsw-alias-label-primary); background: var(--dsw-alias-bg-base); }
*, *::before, *::after { box-sizing: border-box; }
button, textarea { font-family: inherit; }
p { margin: 0; }
[hidden] { display: none !important; }
/* Requested demo variant: title + status, with plain spacing and no dot. */
.tool-summary { margin-left: 8px; }
/* Match the question buttons; add the inset for a concentric composer edge. */
.input-card { --demo-control-radius: var(--dsw-radius-md); border-radius: calc(var(--demo-control-radius) + 8px); }
.input-add, .input-primary { border-radius: var(--demo-control-radius); }
/* Requested brand-blue confirmations; source sizing and disabled state remain. */
.question-footerActions .button-primary { --dsw-alias-button-primary-fill: var(--blue, #165dff); --dsw-alias-button-primary-hover: #0e42d2; --dsw-alias-label-primary-foreground: #fff; }
/* All movement, including source CSS shimmer, follows the parent timeline. */
*, *::before, *::after { transition: none !important; animation-play-state: paused !important; }
/* Only effect nodes consume the clock; the thought row passes it to ::after. */
.shimmer-root, .thought-row::after { animation-delay: var(--demo-animation-time, 0s) !important; }
/* demo-section:assistant-overrides:end */
