:root {
    /* 语义色：涨红 / 跌绿，只用于数字与状态，不做主题色。 */
    --market-up: #e0323c;
    --market-up-soft: #fdeff0;
    --market-down: #12a366;
    --market-down-soft: #eaf7f1;
    --market-amber: #b45309;
    --market-amber-soft: #fff7e6;
    --market-danger: #c2413b;
    --market-danger-soft: #fdf1ef;
    /* 主色：唯一一个「蓝」。可交互的东西（链接、选中态、悬停）才用它，
       涨跌红绿、提醒琥珀都不得挪用到主题色上。 */
    --market-brand: #1576e8;
    --market-brand-strong: #0b5fd0;
    --market-brand-soft: #eaf2fd;
    /* 中性色去绿味：#17211f/#dbe3e1 偏青，换成纯中性灰阶。 */
    --market-ink: #1b1e24;
    --market-line: #e8eaee;
    /* 条目之间的细线：比 --market-line 再淡一档，一排条目连读时只有节奏、
       不出现一堵横线墙。 */
    --market-line-2: #eef0f3;
    --market-panel: #ffffff;
    --market-panel-muted: #f5f6f8;
}

[data-theme="dark"] {
    --market-up: #fb7185;
    --market-up-soft: rgba(244, 63, 94, 0.12);
    --market-down: #34d399;
    --market-down-soft: rgba(16, 185, 129, 0.12);
    --market-amber: #fbbf24;
    --market-amber-soft: rgba(245, 158, 11, 0.12);
    --market-danger: #fb7185;
    --market-danger-soft: rgba(244, 63, 94, 0.12);
    --market-brand: #6cb2f7;
    --market-brand-strong: #9ccbfa;
    --market-brand-soft: rgba(21, 118, 232, 0.18);
    --market-ink: var(--text-primary);
    --market-line: var(--border-color);
    --market-line-2: var(--border-light);
    --market-panel: var(--bg-primary);
    --market-panel-muted: var(--bg-secondary);
}

.header .nav {
    justify-content: center;
}

.header .nav-btn {
    padding: 8px 11px;
    flex: 0 0 auto;
    white-space: nowrap;
}

body.market-page-active .research-workbench {
    display: none;
}

body.market-page-active .main {
    border-radius: 8px;
}

.market-page {
    color: var(--market-ink);
}

.market-page-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 20px;
    padding-bottom: 18px;
    border-bottom: 1px solid var(--market-line);
}

.market-page-head h2 {
    margin: 2px 0 0;
    font-size: 28px;
    line-height: 1.2;
    letter-spacing: 0;
}

.market-kicker {
    color: #1576e8;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: 0;
}

.market-date-controls,
.market-filter-bar,
.market-section-head,
.market-replay-summary {
    display: flex;
    align-items: center;
}

.market-date-controls {
    gap: 8px;
    flex-wrap: wrap;
    justify-content: flex-end;
}

.market-date-controls input,
.market-search {
    height: 36px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
    color: var(--text-primary);
    font: inherit;
    font-size: 13px;
    padding: 0 10px;
}

.market-icon-btn {
    width: 36px;
    height: 36px;
    display: inline-grid;
    place-items: center;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
    color: var(--text-primary);
    font-size: 18px;
    line-height: 1;
    cursor: pointer;
}

.market-icon-btn:hover,
.market-icon-btn:focus-visible {
    border-color: #1576e8;
    color: #1576e8;
    outline: none;
}

.market-state-badge {
    display: inline-flex;
    align-items: center;
    min-height: 28px;
    padding: 4px 9px;
    border: 1px solid var(--market-line);
    border-radius: 999px;
    background: var(--market-panel-muted);
    color: var(--text-secondary);
    font-size: 12px;
    font-style: normal;
    white-space: nowrap;
}

.market-state-badge.is-final {
    border-color: rgba(4, 120, 87, 0.28);
    background: var(--market-down-soft);
    color: var(--market-down);
}

.market-state-badge.is-provisional,
.market-state-badge.is-warning {
    border-color: rgba(180, 83, 9, 0.28);
    background: var(--market-amber-soft);
    color: var(--market-amber);
}

/* Requested session had no snapshot and the API fell back to an earlier one. */
.market-state-badge.is-resolved {
    border-color: rgba(180, 83, 9, 0.28);
    background: var(--market-amber-soft);
    color: var(--market-amber);
}

.market-state-badge.is-snapshot {
    border-color: rgba(100, 116, 139, 0.28);
    background: var(--market-panel-muted);
    color: var(--text-secondary);
}

.market-inline-state {
    min-height: 260px;
    display: grid;
    place-items: center;
    color: var(--text-muted);
    font-size: 14px;
}

.market-inline-state.is-error {
    color: var(--market-amber);
}

.market-alerts {
    margin-top: 14px;
    border-left: 3px solid var(--market-amber);
    background: var(--market-amber-soft);
    color: var(--market-amber);
    font-size: 13px;
}

.market-alerts-details > summary {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 9px 12px;
    color: var(--market-amber);
    font-size: 13px;
    cursor: pointer;
    list-style: none;
}

.market-alerts-details > summary::-webkit-details-marker {
    display: none;
}

.market-alerts-details > summary::after {
    content: '▾';
    margin-left: auto;
    font-size: 11px;
    opacity: .7;
}

.market-alerts-details[open] > summary::after {
    content: '▴';
}

.market-alerts.is-risk {
    border-left-color: var(--market-danger);
    background: var(--market-danger-soft);
}

.market-alerts.is-risk .market-alerts-details > summary {
    color: var(--market-danger);
    font-weight: 600;
}

.market-alerts-body {
    padding: 0 12px 10px;
}

.market-alerts p + p {
    margin-top: 4px;
}

.market-alerts p.is-blocking {
    color: var(--market-danger);
    font-weight: 600;
}

.market-alerts p.is-degraded {
    color: var(--market-amber);
}

.market-alerts p.is-info {
    color: var(--text-secondary);
}

#market-structure-tab-alerts {
    margin-top: 8px;
}

.market-sentiment-band {
    display: grid;
    grid-template-columns: minmax(150px, 0.28fr) minmax(0, 1fr);
    gap: 28px;
    padding: 26px 0;
    border-bottom: 1px solid var(--market-line);
}

.market-score-block {
    display: grid;
    align-content: center;
    border-right: 1px solid var(--market-line);
}

.market-score-block span,
.market-score-block em {
    font-variant-numeric: tabular-nums;
    color: var(--text-muted);
    font-size: 13px;
    font-style: normal;
}

.market-score-block strong {
    font-variant-numeric: tabular-nums;
    margin: 4px 0;
    font-size: 48px;
    line-height: 1;
    font-weight: 750;
    letter-spacing: 0;
}

.market-score-block em {
    font-variant-numeric: tabular-nums;
    color: #1576e8;
    font-weight: 700;
}

.market-sentiment-detail {
    min-width: 0;
}

.market-progress-track {
    height: 8px;
    overflow: hidden;
    border-radius: 4px;
    background: var(--market-panel-muted);
}

.market-progress-track span {
    display: block;
    width: 0;
    height: 100%;
    border-radius: 4px;
    background: #1576e8;
    transition: width 220ms ease;
}

.market-component-bars {
    display: grid;
    gap: 9px;
    margin-top: 16px;
}

.market-component-row {
    display: grid;
    grid-template-columns: minmax(82px, 126px) minmax(80px, 1fr) 42px;
    align-items: center;
    gap: 10px;
    font-size: 12px;
}

.market-component-row > span:first-child {
    overflow: hidden;
    color: var(--text-secondary);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-component-row strong {
    color: var(--text-primary);
    text-align: right;
}

.market-component-track {
    height: 5px;
    overflow: hidden;
    border-radius: 3px;
    background: var(--market-panel-muted);
}

.market-component-track i {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: #1576e8;
}

.market-context-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 12px;
}

.market-context-axis {
    min-width: 0;
    padding: 14px 16px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.market-context-axis-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.market-context-axis > span {
    display: block;
    color: var(--text-muted);
    font-size: 12px;
    margin-bottom: 6px;
}

.market-context-axis strong {
    font-variant-numeric: tabular-nums;
    display: block;
    margin: 8px 0 10px;
    font-size: 28px;
    line-height: 1.1;
    letter-spacing: 0;
}

.market-context-axis-status {
    color: var(--text-muted);
    font-size: 11px;
    font-style: normal;
    white-space: nowrap;
}

.market-context-axis-status.is-hot {
    color: var(--market-up);
}

.market-context-axis-status.is-warm {
    color: var(--market-amber);
}

.market-context-axis-status.is-cool {
    color: var(--market-down);
}

.market-context-axis strong.is-hot {
    color: #dc2626;
}

.market-context-axis strong.is-warm {
    color: #d97706;
}

.market-context-axis strong.is-cool {
    color: var(--market-down);
}

.market-context-axis strong.is-muted {
    color: var(--text-muted);
}

.market-context-track {
    height: 5px;
    overflow: hidden;
    border-radius: 3px;
    background: var(--market-panel-muted);
}

.market-context-track i {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: #1576e8;
}

.market-context-axis-formula {
    margin: 9px 0 5px;
    color: var(--text-secondary);
    font-size: 11px;
}

.market-context-axis-facts {
    font-variant-numeric: tabular-nums;
    display: flex;
    flex-wrap: wrap;
    gap: 4px 8px;
    min-height: 30px;
    color: var(--text-primary);
    font-size: 11px;
    line-height: 1.5;
}

.market-context-axis-facts span {
    white-space: nowrap;
}

.market-context-axis-coverage {
    display: block;
    margin-top: 6px;
    color: var(--text-muted);
    font-size: 10px;
}

.market-context-empty {
    padding: 12px;
    color: var(--text-muted);
    font-size: 13px;
    border: 1px dashed var(--market-line);
    border-radius: 8px;
}

.market-context-help {
    margin-top: 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.market-context-help summary {
    padding: 9px 12px;
    cursor: pointer;
    color: var(--text-primary);
    font-size: 12px;
    font-weight: 700;
    list-style: none;
}

.market-context-help summary::-webkit-details-marker {
    display: none;
}

.market-context-help summary::before {
    content: '＋';
    display: inline-block;
    margin-right: 6px;
    color: var(--market-down);
}

.market-context-help[open] summary::before {
    content: '－';
}

.market-context-help-body {
    padding: 0 12px 11px;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.65;
}

.market-context-help-body p {
    margin: 0 0 8px;
}

.market-context-help-caption {
    color: var(--text-muted);
    font-size: 11px;
}

.market-context-help-body strong {
    color: var(--text-primary);
}

.market-context-help-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 8px;
    margin: 8px 0;
}

.market-context-help-grid div {
    padding: 8px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
}

.market-context-help-grid b,
.market-context-help-grid span {
    display: block;
}

.market-context-help-grid b {
    margin-bottom: 3px;
    color: var(--text-primary);
}

.market-context-help-grid span {
    color: var(--text-secondary);
    font-size: 11px;
}

.market-ranked-theme {
    min-width: 0;
    display: grid;
    gap: 3px;
}

.market-ranked-theme strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-crowding-badge {
    justify-self: start;
    max-width: 100%;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    padding: 2px 6px;
    border-radius: 4px;
    background: var(--market-panel-muted);
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.4;
}

.market-crowding-badge.q-high_rising {
    color: #b91c1c;
    background: rgba(220, 38, 38, 0.10);
}

.market-crowding-badge.q-high_falling {
    color: #b45309;
    background: rgba(217, 119, 6, 0.12);
}

.market-crowding-badge.q-low_rising {
    color: var(--market-down);
    background: var(--market-down-soft);
}

.market-crowding-badge.q-low_falling {
    color: #64748b;
}

.market-section {
    padding: 24px 0;
    border-bottom: 1px solid var(--market-line);
}

.market-section-tight {
    min-width: 0;
    padding-top: 0;
    border-bottom: 0;
}

.market-section-head {
    justify-content: space-between;
    gap: 14px;
    margin-bottom: 14px;
}

.market-section-head h3 {
    margin: 0;
    font-size: 16px;
    letter-spacing: 0;
}

.market-muted {
    color: var(--text-muted);
    font-size: 12px;
}

.market-text-btn {
    border: 0;
    background: transparent;
    color: #1576e8;
    font: inherit;
    font-size: 13px;
    font-weight: 700;
    cursor: pointer;
}

.market-metric-strip {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.market-metric-strip-compact {
    margin: 16px 0;
}

.market-metric-cell {
    min-width: 0;
    padding: 14px 16px;
    border-right: 1px solid var(--market-line);
}

.market-metric-cell:last-child {
    border-right: 0;
}

.market-metric-cell span,
.market-metric-cell small {
    display: block;
    color: var(--text-muted);
    font-size: 11px;
}

.market-metric-cell strong {
    display: block;
    margin: 4px 0 2px;
    overflow: hidden;
    color: var(--text-primary);
    font-size: 20px;
    line-height: 1.2;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.is-up,
.market-metric-cell strong.is-up {
    color: var(--market-up);
}

.is-down,
.market-metric-cell strong.is-down {
    color: var(--market-down);
}

.is-flat {
    color: var(--text-secondary);
}

.market-two-column {
    display: grid;
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 0.85fr);
    gap: 32px;
    padding-top: 24px;
}

.market-ranked-list {
    display: grid;
}

.market-ranked-item {
    display: grid;
    grid-template-columns: 28px minmax(0, 1fr) 66px 64px;
    align-items: center;
    gap: 8px;
    padding: 10px 0;
    border-bottom: 1px solid var(--market-line);
    cursor: pointer;
}

.market-ranked-item:last-child {
    border-bottom: 0;
}

.market-ranked-item b {
    font-variant-numeric: tabular-nums;
    color: #1576e8;
    font-size: 12px;
}

.market-ranked-item strong,
.market-ranked-item span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-ranked-item strong {
    font-size: 13px;
}

.market-ranked-item span {
    color: var(--text-secondary);
    font-size: 12px;
    text-align: right;
}

.market-signal-list {
    display: grid;
    gap: 8px;
    margin-top: 14px;
}

.market-signal-item {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    padding: 9px 10px;
    border-left: 2px solid var(--market-line);
    background: var(--market-panel-muted);
    color: var(--text-secondary);
    font-size: 12px;
}

.market-signal-item.is-risk {
    border-color: var(--market-amber);
}

.market-signal-item.is-positive {
    border-color: var(--market-up);
}

.market-segmented {
    display: inline-flex;
    gap: 2px;
    margin-top: 18px;
    padding: 3px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.market-segmented button {
    min-height: 34px;
    padding: 6px 14px;
    border: 0;
    border-radius: 5px;
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.market-segmented button.active {
    background: var(--market-panel);
    color: #1576e8;
    box-shadow: none;
    font-weight: 700;
}

.market-segmented-small {
    margin: 0;
}

.market-segmented-small button {
    min-height: 30px;
    padding: 4px 10px;
    font-size: 12px;
}

.market-structure-toolbelt {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    margin-top: 18px;
}

.market-structure-toolbelt .market-segmented {
    margin-top: 0;
}

.market-structure-context {
    display: grid;
    gap: 8px;
    margin-top: 12px;
    padding: 11px 13px;
    border: 1px solid var(--market-line);
    border-left: 3px solid #64748b;
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.market-structure-basis {
    display: grid;
    grid-template-columns: max-content minmax(0, 1fr);
    align-items: baseline;
    gap: 8px 12px;
}

.market-structure-basis-label {
    color: var(--text-primary);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.5;
    white-space: nowrap;
}

.market-structure-basis-label.is-live {
    color: var(--market-up);
}

.market-structure-basis-label.is-after-close {
    color: #64748b;
}

.market-structure-basis-label.is-warning {
    color: var(--market-amber);
}

.market-structure-basis-label.is-error {
    color: var(--market-danger);
}

.market-structure-basis-note {
    min-width: 0;
    margin: 0;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.6;
    overflow-wrap: anywhere;
}

.market-structure-basis-matrix {
    border-top: 1px solid var(--market-line);
    padding-top: 7px;
}

.market-structure-basis-matrix > summary {
    width: max-content;
    max-width: 100%;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.6;
    cursor: pointer;
}

.market-structure-basis-matrix > summary:hover,
.market-structure-basis-matrix > summary:focus-visible {
    color: #1576e8;
    outline: none;
}

.market-structure-basis-table {
    display: grid;
    gap: 1px;
    min-width: 640px;
    margin-top: 8px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-line);
    overflow: hidden;
}

.market-structure-basis-table > [role="row"] {
    display: grid;
    grid-template-columns: 110px minmax(190px, 1fr) minmax(220px, 1.15fr);
}

.market-structure-basis-table > [role="row"] > span {
    min-width: 0;
    padding: 7px 9px;
    background: var(--market-panel);
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.55;
    overflow-wrap: anywhere;
}

.market-structure-basis-table > [role="row"].is-head > span {
    background: var(--market-panel-muted);
    color: var(--text-primary);
    font-weight: 700;
}

.market-structure-basis-matrix[open] {
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: thin;
}

.market-structure-basis-matrix[open] .market-structure-basis-table {
    width: max-content;
    min-width: 100%;
}

.market-provider-switch {
    margin-left: auto;
}

.market-provider-switch button {
    min-height: 30px;
    padding: 4px 10px;
    font-size: 12px;
}

.market-provider-switch button.active {
    color: #1576e8;
}

.market-source-note {
    margin-bottom: 12px;
    padding: 6px 10px;
    border: 1px dashed var(--market-line);
    border-radius: 6px;
    background: var(--market-panel-muted);
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.6;
}

.market-promotion-trend-board {
    margin-top: 16px;
}

.market-promotion-trend-summary {
    margin-bottom: 8px;
}

.market-promotion-trend-verdict {
    display: flex;
    flex-direction: column;
    gap: 2px;
    padding: 10px 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.market-promotion-trend-verdict strong {
    font-size: 14px;
}

.market-promotion-trend-verdict small {
    color: var(--text-secondary);
}

.market-promotion-trend-verdict small.market-promotion-trend-help {
    margin-top: 4px;
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.7;
    border-top: 1px dashed var(--market-line);
    padding-top: 6px;
}

.market-promotion-trend-chart {
    min-height: 300px;
}

.market-promotion-detail {
    margin-top: 12px;
    padding: 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.market-promotion-detail.hidden {
    display: none;
}

.market-promotion-detail-head {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.market-promotion-detail-head strong {
    font-size: 14px;
}

.market-promotion-detail-close {
    margin-left: auto;
    padding: 3px 12px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    font-size: 12px;
}

.market-promotion-detail-close:hover {
    color: var(--text-primary);
    border-color: var(--text-secondary);
}

.market-promotion-detail-section {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.market-promotion-detail-section-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

.market-promotion-detail-section-head strong {
    font-size: 13px;
}

.market-promotion-detail-section-head span {
    font-size: 12px;
    color: var(--text-secondary);
}

.market-promotion-detail-cols {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 10px;
}

@media (max-width: 900px) {
    .market-promotion-detail-cols {
        grid-template-columns: 1fr;
    }
}

.market-promotion-detail-col-title {
    font-size: 12px;
    font-weight: 600;
    margin-bottom: 4px;
}

.market-promotion-detail-col-title.up {
    color: var(--market-up, #dc2626);
}

.market-promotion-detail-col-title.down {
    color: var(--market-down, #16a34a);
}

.market-promotion-detail-stocks {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.market-promotion-detail-stock {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel, transparent);
    font-size: 12px;
}

.market-promotion-detail-stock b {
    font-weight: 600;
}

.market-promotion-detail-stock .up {
    color: var(--market-up, #dc2626);
}

.market-promotion-detail-stock .down {
    color: var(--market-down, #16a34a);
}

.market-promotion-detail-empty {
    font-size: 12px;
    color: var(--text-muted);
    padding: 3px 0;
}

.market-tab-panel {
    display: none;
    padding-top: 16px;
}

.market-tab-panel.active {
    display: block;
}

.market-filter-bar {
    justify-content: space-between;
    gap: 10px;
    flex-wrap: wrap;
}

.market-search {
    width: min(240px, 100%);
}

.market-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--market-line);
    border-radius: 8px;
}

.market-table {
    width: 100%;
    min-width: 720px;
    border-collapse: collapse;
    background: var(--market-panel);
    font-size: 12px;
}

.market-table th,
.market-table td {
    height: 42px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--market-line);
    text-align: right;
    white-space: nowrap;
}

.market-table th {
    background: var(--market-panel-muted);
    color: var(--text-muted);
    font-weight: 700;
}

.market-table th:nth-child(-n+2),
.market-table td:nth-child(-n+2) {
    text-align: left;
}

.market-table tbody tr:last-child td {
    border-bottom: 0;
}

.market-table tbody tr {
    cursor: pointer;
}

.market-table tbody tr:hover,
.market-table tbody tr.is-selected {
    background: var(--market-panel-muted);
}

.market-table input[type="checkbox"] {
    width: 15px;
    height: 15px;
    accent-color: #1576e8;
}

.market-rotation-wrap {
    max-height: 560px;
}

/* 异动监控（anomaly monitor tab） */
.market-anomaly-filter {
    align-items: center;
}

.market-anomaly-types {
    margin-right: auto;
}

.market-anomaly-badge {
    display: inline-block;
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    background: var(--market-panel-muted);
}

.market-anomaly-badge.is-up {
    color: #cf4542;
    background: rgba(207, 69, 66, 0.12);
}

.market-anomaly-badge.is-down {
    color: #41ad42;
    background: rgba(65, 173, 66, 0.12);
}

.market-anomaly-badge.market-anomaly-limit.is-up {
    color: #fff;
    background: #cf4542;
}

.market-anomaly-badge.market-anomaly-limit.is-down {
    color: #fff;
    background: #41ad42;
}

/* 监管异动监控池：市场徽章 / 剩余天数 / 监控期 / Tab 计数 */
.market-market-badge {
    font-weight: 600;
}

.market-market-badge.market-market-sh {
    color: #0b5fd0;
    background: rgba(11, 95, 208, 0.10);
}

.market-market-badge.market-market-sz {
    color: #047857;
    background: rgba(4, 120, 87, 0.10);
}

.market-market-badge.market-market-bj {
    color: #9d174d;
    background: rgba(157, 23, 77, 0.10);
}

.market-anomaly-window {
    line-height: 1.4;
    white-space: nowrap;
}

.market-anomaly-reason {
    white-space: normal;
    min-width: 220px;
    max-width: 420px;
}

.market-anomaly-remain {
    display: inline-block;
    padding: 2px 10px;
    border-radius: 999px;
    font-weight: 700;
    font-size: 11px;
}

.market-anomaly-remain.is-hot {
    color: #dc2626;
    background: rgba(220, 38, 38, 0.12);
}

.market-anomaly-remain.is-warm {
    color: #d97706;
    background: rgba(217, 119, 6, 0.12);
}

.market-anomaly-remain.is-cool {
    color: #059669;
    background: rgba(5, 150, 105, 0.12);
}

.market-anomaly-remain.is-expired {
    color: var(--text-muted);
    background: var(--market-panel-muted);
}

.market-anomaly-types button small {
    margin-left: 4px;
    opacity: 0.65;
    font-size: 10px;
}

.market-rotation-table {
    min-width: 900px;
}

.market-rotation-table th,
.market-rotation-table td,
.market-rotation-table th:nth-child(-n+2),
.market-rotation-table td:nth-child(-n+2) {
    min-width: 72px;
    text-align: center;
}

.market-rotation-table th:first-child,
.market-rotation-table td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    min-width: 170px;
    text-align: left;
}

.market-rotation-table th:first-child {
    z-index: 2;
}

.market-rotation-table td:first-child {
    background: var(--market-panel);
}

.market-rotation-table tr:hover td:first-child {
    background: var(--market-panel-muted);
}

.market-rotation-theme strong,
.market-rotation-theme small,
.market-rotation-cell strong,
.market-rotation-cell small {
    display: block;
}

.market-rotation-theme-button {
    display: block;
    width: 100%;
    padding: 0;
    border: 0;
    color: inherit;
    background: transparent;
    text-align: left;
    cursor: pointer;
    font: inherit;
}

.market-rotation-theme-button:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 2px;
}

.market-rotation-theme small,
.market-rotation-cell small {
    margin-top: 2px;
    color: var(--text-muted);
    font-size: 10px;
}

.market-rotation-cell {
    box-shadow: inset 0 0 0 1px transparent;
}

.market-rotation-cell.is-rank-1 {
    background: var(--market-up-soft);
    color: var(--market-up);
    box-shadow: inset 0 0 0 1px rgba(220, 38, 38, 0.16);
}

.market-rotation-cell.is-rank-2 {
    background: var(--market-amber-soft);
    color: var(--market-amber);
}

.market-rotation-cell.is-rank-3 {
    background: var(--market-down-soft);
    color: var(--market-down);
}

.market-rotation-cell.is-missing {
    color: var(--text-muted);
    background: var(--market-panel-muted);
}

.market-empty-row {
    height: 110px !important;
    color: var(--text-muted);
    text-align: center !important;
}

.market-type-badge {
    display: inline-block;
    min-width: 34px;
    padding: 2px 6px;
    border-radius: 4px;
    text-align: center;
    font-size: 11px;
    font-weight: 700;
}

.market-type-badge.is-u {
    background: var(--market-up-soft);
    color: var(--market-up);
}

.market-type-badge.is-d {
    background: var(--market-down-soft);
    color: var(--market-down);
}

.market-type-badge.is-z {
    background: var(--market-amber-soft);
    color: var(--market-amber);
}

.market-ladder-grid {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
    align-items: start;
    gap: 12px;
}

.market-ladder-column {
    border: 1px solid var(--market-line);
    border-radius: 8px;
    overflow: hidden;
    background: var(--market-panel);
}

.market-ladder-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 10px 12px;
    background: var(--market-panel-muted);
    border-bottom: 1px solid var(--market-line);
}

.market-ladder-head strong {
    font-size: 14px;
}

.market-ladder-stock {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    padding: 9px 12px;
    border-bottom: 1px solid var(--market-line);
    font-size: 12px;
    cursor: pointer;
}

.market-ladder-stock:last-child {
    border-bottom: 0;
}

.market-ladder-stock small {
    color: var(--text-muted);
}

.market-replay-summary {
    justify-content: space-between;
    gap: 24px;
    padding: 28px 0 22px;
}

.market-replay-summary h3 {
    margin: 4px 0 8px;
    font-size: 24px;
    letter-spacing: 0;
}

.market-replay-summary p {
    max-width: 760px;
    color: var(--text-secondary);
    font-size: 14px;
}

.market-replay-score {
    min-width: 110px;
    text-align: right;
}

.market-replay-score strong,
.market-replay-score span {
    display: block;
}

.market-replay-score strong {
    font-size: 42px;
    line-height: 1;
}

.market-replay-score span {
    margin-top: 6px;
    color: var(--text-muted);
    font-size: 12px;
}

.market-promotion-list {
    display: grid;
    gap: 8px;
}

.market-promotion-item {
    display: grid;
    grid-template-columns: 68px minmax(80px, 1fr) 48px;
    align-items: center;
    gap: 10px;
    font-size: 12px;
}

.market-promotion-item .market-component-track i {
    background: var(--market-up);
}

.market-theme-ribbon {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 8px;
}

.market-theme-item {
    min-width: 0;
    padding: 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    cursor: pointer;
}

.market-theme-item span,
.market-theme-item strong,
.market-theme-item small {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-theme-item span,
.market-theme-item small {
    color: var(--text-muted);
    font-size: 11px;
}

.market-theme-item strong {
    margin: 5px 0;
    font-size: 14px;
}

.market-command-btn {
    min-height: 34px;
    padding: 0 13px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-ink);
    color: var(--market-panel);
    font: inherit;
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
}

.market-command-btn:hover,
.market-command-btn:focus-visible {
    opacity: 0.88;
}

.market-command-btn:disabled {
    cursor: wait;
    opacity: 0.55;
}

.market-operation-state {
    color: var(--text-muted);
    font-size: 12px;
}

.market-operation-state.is-success {
    color: var(--market-down);
}

.market-operation-state.is-warning,
.market-operation-state.is-error {
    color: var(--market-amber);
}

.market-journal-section {
    padding-top: 24px;
}

.market-note-editor {
    width: 100%;
    min-height: 132px;
    resize: vertical;
    padding: 12px 14px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
    color: var(--market-ink);
    font: inherit;
    font-size: 14px;
    line-height: 1.65;
}

.market-form-actions,
.market-section-actions {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
}

.market-form-actions {
    margin-top: 10px;
}

.market-inline-field {
    display: grid;
    flex: 1;
    gap: 5px;
    color: var(--text-muted);
    font-size: 12px;
}

.market-inline-field input,
.market-observation-form input,
.market-observation-form select {
    width: 100%;
    min-width: 0;
    height: 36px;
    padding: 0 10px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
    color: var(--market-ink);
    font: inherit;
    font-size: 13px;
}

.market-journal-list {
    margin-top: 10px;
    border-top: 1px solid var(--market-line);
}

.market-journal-row {
    display: grid;
    grid-template-columns: minmax(150px, 0.7fr) minmax(220px, 1.8fr) auto;
    align-items: center;
    gap: 16px;
    min-height: 62px;
    padding: 10px 0;
    border-bottom: 1px solid var(--market-line);
}

.market-observation-row {
    grid-template-columns: minmax(150px, 0.7fr) minmax(240px, 1.8fr) minmax(92px, auto) 34px;
}

.market-journal-main,
.market-journal-detail,
.market-observation-result {
    min-width: 0;
}

.market-journal-main strong,
.market-journal-main span,
.market-journal-detail span,
.market-journal-detail small,
.market-observation-result strong {
    display: block;
}

.market-journal-main strong,
.market-journal-detail span {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-journal-main span,
.market-journal-detail small {
    margin-top: 3px;
    color: var(--text-muted);
    font-size: 11px;
}

.market-observation-result {
    text-align: right;
}

.market-observation-result strong {
    margin-top: 4px;
    font-size: 13px;
}

.market-result-badge {
    display: inline-flex;
    min-height: 22px;
    align-items: center;
    padding: 0 7px;
    border-radius: 4px;
    background: var(--market-panel-muted);
    color: var(--text-muted);
    font-size: 11px;
}

.market-result-badge.is-hit {
    background: var(--market-up-soft);
    color: var(--market-up);
}

.market-result-badge.is-missed,
.market-result-badge.is-invalidated {
    background: var(--market-down-soft);
    color: var(--market-down);
}

.market-result-badge.is-planned,
.market-result-badge.is-unavailable {
    background: var(--market-amber-soft);
    color: var(--market-amber);
}

.market-row-icon,
.market-row-icon-spacer {
    width: 34px;
    height: 34px;
}

.market-row-icon {
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: var(--text-muted);
    font-size: 20px;
    cursor: pointer;
}

.market-row-icon:hover,
.market-row-icon:focus-visible {
    background: var(--market-panel-muted);
    color: var(--market-ink);
}

.market-observation-form {
    display: grid;
    grid-template-columns: minmax(160px, 1.2fr) repeat(4, minmax(130px, 1fr));
    gap: 12px;
    margin-top: 14px;
}

.market-observation-form > label {
    display: grid;
    min-width: 0;
    gap: 5px;
    color: var(--text-muted);
    font-size: 12px;
}

.market-form-wide {
    grid-column: 1 / -1;
}

.market-input-suffix {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 28px;
    align-items: center;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
}

.market-input-suffix input {
    border: 0;
    background: transparent;
}

.market-input-suffix span {
    color: var(--text-muted);
    font-size: 12px;
    text-align: center;
}

@media (max-width: 1180px) {
    .header {
        align-items: flex-start;
        flex-wrap: wrap;
    }

    .header .nav {
        order: 3;
        width: 100%;
        overflow-x: auto;
        justify-content: flex-start;
        flex-wrap: nowrap;
    }

    .market-metric-strip {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .market-metric-cell:nth-child(3n) {
        border-right: 0;
    }

    .market-metric-cell:nth-child(n+4) {
        border-top: 1px solid var(--market-line);
    }

    .market-theme-ribbon {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }

    .market-observation-form {
        grid-template-columns: repeat(3, minmax(0, 1fr));
    }
}

@media (max-width: 760px) {
    .market-context-grid {
        grid-template-columns: 1fr;
    }

    .market-context-help-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .header {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        align-items: center;
    }

    .header .nav {
        grid-column: 1 / -1;
        grid-row: 2;
        width: 100%;
        overflow-x: auto;
        flex-wrap: nowrap;
        scrollbar-width: none;
    }

    .header .nav::-webkit-scrollbar {
        display: none;
    }

    .header .theme-toggle {
        grid-column: 2;
        grid-row: 1;
    }

    .market-page-head,
    .market-sentiment-band,
    .market-two-column,
    .market-replay-summary {
        display: grid;
        grid-template-columns: 1fr;
    }

    .market-date-controls {
        justify-content: flex-start;
    }

    .market-score-block {
        padding-bottom: 18px;
        border-right: 0;
        border-bottom: 1px solid var(--market-line);
    }

    .market-score-block strong {
        font-variant-numeric: tabular-nums;
        font-size: 40px;
    }

    .market-two-column {
        gap: 24px;
    }

    .market-metric-strip {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .market-metric-cell,
    .market-metric-cell:nth-child(3n) {
        border-right: 1px solid var(--market-line);
    }

    .market-metric-cell:nth-child(2n) {
        border-right: 0;
    }

    .market-metric-cell:nth-child(n+3) {
        border-top: 1px solid var(--market-line);
    }

    .market-component-row {
        grid-template-columns: 88px minmax(70px, 1fr) 38px;
    }

    .market-theme-ribbon {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    .market-replay-score {
        text-align: left;
    }

    .market-observation-form {
        grid-template-columns: 1fr 1fr;
    }

    .market-journal-row,
    .market-observation-row {
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 8px 12px;
    }

    .market-journal-detail {
        grid-column: 1 / -1;
        grid-row: 2;
    }

    .market-observation-result {
        grid-column: 2;
        grid-row: 1;
    }

    .market-observation-row .market-row-icon,
    .market-observation-row .market-row-icon-spacer {
        grid-column: 2;
        grid-row: 2;
        justify-self: end;
    }
}

@media (max-width: 480px) {
    .market-context-grid {
        grid-template-columns: 1fr;
    }

    .market-page-head h2 {
        font-size: 24px;
    }

    .market-date-controls input {
        flex: 1;
        min-width: 150px;
    }

    .market-segmented {
        display: grid;
        grid-template-columns: repeat(2, 1fr);
        width: 100%;
    }

    .market-segmented-small {
        display: flex;
        width: auto;
        overflow-x: auto;
    }

    .market-metric-cell {
        padding: 12px;
    }

    .market-metric-cell strong {
        font-size: 18px;
    }

    .market-theme-ribbon {
        grid-template-columns: 1fr;
    }

    .market-observation-form {
        grid-template-columns: 1fr;
    }

    .market-form-wide {
        grid-column: 1;
    }

    .market-form-actions,
    .market-section-actions {
        align-items: stretch;
        flex-direction: column;
    }

    .market-form-actions .market-command-btn,
    .market-section-actions .market-command-btn {
        width: 100%;
    }
}

/* 涨停异动工作台 */
.market-event-page-head {
    align-items: flex-end;
}

.market-page-description {
    max-width: 660px;
    margin: 8px 0 0;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.6;
}

.market-command-btn-light {
    border-color: var(--market-line);
    background: var(--market-panel);
    color: var(--text-primary);
}

.market-command-btn-accent {
    border-color: var(--market-accent, #1576e8);
    background: var(--market-accent, #1576e8);
    color: #ffffff;
}

.market-command-btn-accent:hover,
.market-command-btn-accent:focus-visible {
    background: var(--market-accent-strong, #0b5fd0);
    border-color: var(--market-accent-strong, #0b5fd0);
}

.market-event-content {
    display: grid;
    gap: 16px;
    padding-top: 18px;
}

.market-event-hero,
.market-event-panel {
    border: 1px solid var(--market-line);
    background: var(--market-panel);
    box-shadow: none;
}

.market-event-hero {
    display: flex;
    align-items: stretch;
    justify-content: space-between;
    gap: 24px;
    padding: 24px 26px;
    border-left: 4px solid #f97316;
}

.market-event-hero-main {
    min-width: 0;
}

.market-event-eyebrow,
.market-event-title-row,
.market-event-tags,
.market-event-pulse-legend {
    display: flex;
    align-items: center;
    gap: 9px;
    flex-wrap: wrap;
}

.market-event-eyebrow {
    color: var(--text-muted);
    font-size: 12px;
}

.market-event-title-row {
    gap: 12px;
    margin-top: 12px;
}

.market-event-title-row h3 {
    margin: 0;
    font-size: 30px;
    letter-spacing: 0;
}

.market-event-symbol {
    padding: 4px 8px;
    border: 1px solid var(--market-line);
    border-radius: 4px;
    background: var(--market-panel-muted);
    font-size: 12px;
}

.market-event-thesis {
    max-width: 760px;
    margin: 10px 0 14px;
    color: var(--text-secondary);
    font-size: 14px;
    line-height: 1.7;
}

.market-event-tag {
    display: inline-flex;
    min-height: 24px;
    align-items: center;
    padding: 0 9px;
    border: 1px solid var(--market-line);
    border-radius: 999px;
    background: var(--market-panel-muted);
    color: var(--text-secondary);
    font-size: 11px;
}

.market-event-tag.is-primary {
    border-color: rgba(249, 115, 22, 0.3);
    background: #fff7ed;
    color: #c2410c;
    font-weight: 700;
}

[data-theme="dark"] .market-event-tag.is-primary {
    background: rgba(249, 115, 22, 0.12);
}

.market-event-hero-quote {
    display: grid;
    align-content: center;
    min-width: 160px;
    padding-left: 24px;
    border-left: 1px solid var(--market-line);
    text-align: right;
}

.market-event-hero-quote span,
.market-event-hero-quote small {
    color: var(--text-muted);
    font-size: 12px;
}

.market-event-hero-quote strong {
    margin: 4px 0;
    font-size: 38px;
    line-height: 1;
}

.market-event-metrics {
    margin-top: 0;
}

.market-event-grid {
    display: grid;
    grid-template-columns: minmax(0, 1.08fr) minmax(360px, 0.92fr);
    gap: 16px;
}

.market-event-panel {
    min-width: 0;
    padding: 18px 20px;
}

.market-event-panel .market-section-head {
    margin-bottom: 14px;
}

.market-event-timeline {
    display: grid;
    gap: 0;
}

.market-event-timeline-item {
    display: grid;
    grid-template-columns: 12px 72px minmax(0, 1fr);
    gap: 12px;
    min-height: 58px;
    align-items: start;
    position: relative;
}

.market-event-timeline-item:not(:last-child)::after {
    content: '';
    position: absolute;
    top: 12px;
    bottom: 0;
    left: 5px;
    width: 1px;
    background: var(--market-line);
}

.market-event-timeline-dot {
    width: 11px;
    height: 11px;
    margin-top: 3px;
    border: 3px solid var(--market-panel);
    border-radius: 50%;
    background: #94a3b8;
    box-shadow: 0 0 0 1px #94a3b8;
    z-index: 1;
}

.market-event-timeline-dot.is-hot { background: #ef4444; box-shadow: 0 0 0 1px #ef4444; }
.market-event-timeline-dot.is-warn { background: #f59e0b; box-shadow: 0 0 0 1px #f59e0b; }
.market-event-timeline-dot.is-steady { background: var(--market-down); box-shadow: 0 0 0 1px var(--market-down); }
.market-event-timeline-dot.is-close { background: #1576e8; box-shadow: 0 0 0 1px #1576e8; }

.market-event-timeline-time {
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.4;
}

.market-event-timeline-copy strong,
.market-event-timeline-copy span {
    display: block;
}

.market-event-timeline-copy strong {
    font-size: 13px;
}

.market-event-timeline-copy span {
    margin-top: 3px;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.5;
}

.market-event-signal-bars {
    display: grid;
    gap: 13px;
}

.market-event-signal-row {
    display: grid;
    grid-template-columns: 74px minmax(0, 1fr) 30px;
    align-items: center;
    gap: 10px;
    color: var(--text-secondary);
    font-size: 12px;
}

.market-event-signal-row strong {
    color: var(--text-primary);
    font-size: 12px;
    text-align: right;
}

.market-event-signal-track {
    height: 8px;
    overflow: hidden;
    border-radius: 999px;
    background: var(--market-panel-muted);
}

.market-event-signal-track i {
    display: block;
    height: 100%;
    border-radius: inherit;
}

.market-event-signal-track i.is-up { background: #ef4444; }
.market-event-signal-track i.is-blue { background: #1576e8; }
.market-event-signal-track i.is-amber { background: #f59e0b; }
.market-event-signal-track i.is-purple { background: #0b5fd0; }
.market-event-signal-track i.is-orange { background: #f97316; }

.market-event-verdict {
    display: grid;
    gap: 4px;
    margin-top: 18px;
    padding: 12px 14px;
    border-left: 3px solid #1576e8;
    background: var(--market-panel-muted);
}

.market-event-verdict strong { font-size: 13px; }
.market-event-verdict span { color: var(--text-secondary); font-size: 12px; line-height: 1.5; }

.market-event-pulse-panel {
    padding-bottom: 20px;
}

.market-event-pulse-chart {
    display: grid;
    grid-template-columns: repeat(5, minmax(0, 1fr));
    gap: 14px;
    min-height: 220px;
    padding: 16px 14px 0;
    border-top: 1px solid var(--market-line);
    background: linear-gradient(to top, var(--market-panel-muted) 1px, transparent 1px) 0 100% / 100% 44px;
}

.market-event-pulse-column {
    display: grid;
    grid-template-rows: 18px 1fr auto auto;
    align-items: end;
    gap: 6px;
    min-width: 0;
    text-align: center;
}

.market-event-pulse-value { color: var(--text-secondary); font-size: 11px; }

.market-event-pulse-bar {
    display: flex;
    height: 150px;
    align-items: flex-end;
    justify-content: center;
    padding: 0 12px;
    border-bottom: 1px solid var(--market-line);
}

.market-event-pulse-bar i {
    display: block;
    width: min(42px, 70%);
    min-height: 14px;
    border-radius: 5px 5px 0 0;
}

.market-event-pulse-bar i.is-hot { background: #ef4444; }
.market-event-pulse-bar i.is-warm { background: #f59e0b; }
.market-event-pulse-bar i.is-cool { background: var(--market-down); }
.market-event-pulse-column strong { font-size: 12px; }
.market-event-pulse-column small { color: var(--text-muted); font-size: 10px; }

.market-event-pulse-legend {
    justify-content: flex-end;
    margin-top: 14px;
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-pulse-legend i {
    display: inline-block;
    width: 9px;
    height: 9px;
    margin-right: 4px;
    border-radius: 2px;
}

.market-event-pulse-legend i.is-hot { background: #ef4444; }
.market-event-pulse-legend i.is-warm { background: #f59e0b; }
.market-event-pulse-legend i.is-cool { background: var(--market-down); }

.market-event-theme-network {
    display: grid;
    grid-template-columns: 150px minmax(0, 1fr);
    gap: 16px;
    align-items: start;
}

.market-event-theme-core {
    display: grid;
    gap: 4px;
    min-height: 98px;
    align-content: center;
    padding: 14px;
    border: 1px solid rgba(249, 115, 22, 0.3);
    background: #fff7ed;
}

[data-theme="dark"] .market-event-theme-core { background: rgba(249, 115, 22, 0.1); }
.market-event-theme-core span,
.market-event-theme-core small { color: #c2410c; font-size: 11px; }
.market-event-theme-core strong { font-size: 16px; }

.market-event-theme-links {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 8px;
}

.market-event-theme-link {
    display: grid;
    gap: 4px;
    min-height: 98px;
    align-content: center;
    padding: 12px;
    border: 1px solid var(--market-line);
    background: var(--market-panel-muted);
}

.market-event-theme-link span { overflow: hidden; color: var(--text-secondary); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
.market-event-theme-link strong { color: #1576e8; font-size: 18px; }
.market-event-theme-link small { color: var(--text-muted); font-size: 10px; line-height: 1.45; }
.market-event-theme-link.is-candidate { border-color: rgba(21, 118, 232, 0.42); background: #eaf2fd; }

.market-event-theme-summary {
    display: grid;
    gap: 4px;
    min-height: 98px;
    align-content: center;
    padding: 12px;
    border-left: 2px solid #94a3b8;
    background: var(--market-panel-muted);
}

.market-event-theme-summary.is-confirmed { border-left-color: var(--market-down); }
.market-event-theme-summary span,
.market-event-theme-summary small { color: var(--text-secondary); font-size: 11px; }
.market-event-theme-summary strong { font-size: 14px; }

.market-event-theme-membership {
    grid-column: 1 / -1;
    display: grid;
    gap: 9px;
    padding-top: 12px;
    border-top: 1px solid var(--market-line);
}

.market-event-theme-section-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.market-event-theme-section-head strong { font-size: 13px; }
.market-event-theme-section-head span { color: var(--text-muted); font-size: 11px; text-align: right; }

.market-event-peer-list {
    grid-column: 1 / -1;
    display: grid;
    gap: 8px;
    padding-top: 12px;
    border-top: 1px solid var(--market-line);
}

.market-event-peer-list button {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
    min-height: 36px;
    padding: 7px 10px;
    border: 1px solid transparent;
    background: transparent;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.market-event-peer-list button:hover { border-color: var(--market-line); background: var(--market-panel-muted); }
.market-event-peer-list button strong { font-size: 12px; }
.market-event-peer-list button small { color: var(--text-muted); font-size: 11px; }

.market-event-echelon {
    grid-column: 1 / -1;
    margin-top: 10px;
    border-top: 1px solid var(--market-line);
    padding-top: 10px;
}

.market-event-theme-matrix { margin-top: 14px; }
.market-event-theme-matrix .market-event-echelon { margin-top: 0; border-top: none; padding-top: 0; }
.market-event-theme-matrix .market-event-peer-btn small b { font-weight: 600; }

.market-event-echelon-title {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-primary);
    margin-bottom: 8px;
}

.market-event-echelon-group {
    margin-bottom: 8px;
}

.market-event-echelon-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 4px;
}

.market-event-echelon-head span {
    font-size: 12px;
    font-weight: 600;
    color: var(--text-primary);
}

.market-event-echelon-head small {
    font-size: 10px;
    color: var(--text-muted);
}

.market-event-echelon-items {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.market-event-peer-btn {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    padding: 5px 10px;
    border: 1px solid var(--market-line);
    border-radius: 5px;
    background: transparent;
    cursor: pointer;
    transition: border-color 0.15s, background 0.15s;
}

.market-event-peer-btn:hover { border-color: var(--market-accent, #1576e8); background: var(--market-panel-muted); }
.market-event-peer-btn.is-self { border-color: var(--market-hot, #e74c3c); background: rgba(231, 76, 60, 0.06); }
.market-event-peer-btn strong { font-size: 12px; color: var(--text-primary); }
.market-event-peer-btn small { font-size: 10px; color: var(--text-muted); }

.market-event-orderbook { display: grid; gap: 0; }

.market-event-orderbook-row {
    display: grid;
    grid-template-columns: 70px minmax(90px, 1fr) auto;
    gap: 10px;
    align-items: center;
    min-height: 42px;
    border-bottom: 1px solid var(--market-line);
}

.market-event-orderbook-row:last-child { border-bottom: 0; }
.market-event-orderbook-row span { color: var(--text-muted); font-size: 11px; }
.market-event-orderbook-row strong { font-size: 13px; }
.market-event-orderbook-row small { color: var(--text-secondary); font-size: 11px; text-align: right; }

.market-event-evidence-row {
    display: grid;
    grid-template-columns: 92px minmax(88px, auto) minmax(0, 1fr);
    gap: 12px;
    align-items: center;
    min-height: 40px;
    border-bottom: 1px solid var(--market-line);
}

.market-event-evidence-row:last-child { border-bottom: 0; }
.market-event-evidence-row span { color: var(--text-muted); font-size: 11px; }
.market-event-evidence-row strong { color: var(--text-primary); font-size: 13px; }
.market-event-evidence-row small { color: var(--text-secondary); font-size: 11px; line-height: 1.45; }

.market-event-pulse-chart {
    display: block;
    min-height: 0;
    padding: 0;
    border-top: 0;
    background: transparent;
}

.market-event-boundary-list {
    display: grid;
    border-top: 1px solid var(--market-line);
}

.market-event-boundary-row {
    display: grid;
    grid-template-columns: minmax(120px, 0.8fr) 66px minmax(0, 2.4fr);
    gap: 12px;
    align-items: center;
    min-height: 44px;
    border-bottom: 1px solid var(--market-line);
}

.market-event-boundary-row:last-child { border-bottom: 0; }
.market-event-boundary-row span { color: var(--text-primary); font-size: 12px; }
.market-event-boundary-row strong { font-size: 11px; text-align: center; }
.market-event-boundary-row strong.is-available { color: var(--market-down); }
.market-event-boundary-row strong.is-unavailable { color: #b45309; }
.market-event-boundary-row small { color: var(--text-secondary); font-size: 11px; line-height: 1.45; }
.market-event-history-panel { padding-bottom: 16px; }
.market-event-history-table { min-width: 760px; }
.market-event-outcome { color: #1576e8; font-size: 11px; }

.market-event-content {
    grid-template-columns: 320px minmax(0, 1fr);
    align-items: start;
}

.market-event-picker {
    display: flex;
    flex-direction: column;
    max-height: calc(100vh - 140px);
    padding: 16px;
    border: 1px solid var(--market-line);
    background: var(--market-panel);
    box-shadow: none;
    position: sticky;
    top: 12px;
}

.market-event-picker .market-section-head {
    margin-bottom: 12px;
}

.market-event-picker-filters {
    display: grid;
    gap: 10px;
    margin-bottom: 12px;
}

.market-event-picker-body {
    display: grid;
    gap: 6px;
    min-height: 140px;
    overflow-y: auto;
}

.market-event-picker-row {
    display: grid;
    gap: 4px;
    width: 100%;
    padding: 10px 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.market-event-picker-row:hover {
    border-color: rgba(249, 115, 22, 0.45);
    background: #fff7ed;
}

[data-theme="dark"] .market-event-picker-row:hover {
    background: rgba(249, 115, 22, 0.1);
}

.market-event-picker-row.is-active {
    border-color: #f97316;
    background: #fff7ed;
}

[data-theme="dark"] .market-event-picker-row.is-active {
    background: rgba(249, 115, 22, 0.14);
}

.market-event-picker-line {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 0;
}

.market-event-picker-line strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 14px;
}

.market-event-picker-sub {
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-detail {
    display: grid;
    gap: 16px;
    min-width: 0;
}

@media (max-width: 1180px) {
    .market-event-content {
        grid-template-columns: 1fr;
    }
    .market-event-picker {
        position: static;
        max-height: none;
    }
}

@media (max-width: 900px) {
    .market-event-grid { grid-template-columns: 1fr; }
    .market-event-theme-network { grid-template-columns: 1fr; }
    .market-event-theme-links { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .market-event-theme-membership { grid-column: 1; }
}

@media (max-width: 640px) {
    .market-event-hero { display: grid; grid-template-columns: 1fr; padding: 20px; }
    .market-event-hero-quote { min-width: 0; padding: 14px 0 0; border-top: 1px solid var(--market-line); border-left: 0; text-align: left; }
    .market-event-title-row h3 { font-size: 25px; }
    .market-event-theme-links { grid-template-columns: 1fr; }
    .market-event-pulse-chart { gap: 6px; padding-right: 4px; padding-left: 4px; }
    .market-event-pulse-bar { padding: 0 4px; }
    .market-event-pulse-column strong { font-size: 11px; }
    .market-event-timeline-item { grid-template-columns: 12px 58px minmax(0, 1fr); gap: 8px; }\n    .market-event-evidence-row,\n    .market-event-boundary-row { grid-template-columns: 1fr; gap: 4px; padding: 9px 0; align-items: start; }\n    .market-event-evidence-row strong,\n    .market-event-boundary-row strong { text-align: left; }
}

/* Event research workspace */
.market-event-content {
    grid-template-columns: 292px minmax(0, 1fr);
    gap: 18px;
    align-items: start;
}

.market-event-picker {
    max-height: calc(100vh - 132px);
    padding: 14px;
    border-radius: 6px;
    box-shadow: none;
}

.market-event-picker .market-section-head {
    align-items: start;
    margin-bottom: 12px;
}

.market-event-picker .market-section-head > div {
    display: grid;
    gap: 3px;
}

.market-event-picker-filters {
    gap: 9px;
}

.market-event-queue-controls {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.market-event-sort-field {
    display: flex;
    min-width: 0;
    align-items: center;
    gap: 7px;
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-sort-field select {
    min-width: 112px;
    height: 30px;
    border: 1px solid var(--market-line);
    border-radius: 4px;
    background: var(--market-panel);
    color: var(--text-primary);
    font: inherit;
}

.market-event-queue-controls .market-text-btn {
    padding: 0;
    color: var(--text-secondary);
    font-size: 11px;
}

.market-event-queue-controls .market-text-btn:disabled {
    color: var(--text-muted);
    cursor: default;
}

.market-event-picker-body {
    gap: 4px;
}

.market-event-picker-row {
    gap: 5px;
    padding: 9px 10px;
    border-radius: 5px;
    background: transparent;
}

.market-event-picker-row:hover,
.market-event-picker-row.is-active {
    background: var(--market-panel-muted);
}

.market-event-picker-row.is-active {
    border-left: 3px solid #f97316;
    padding-left: 8px;
}

.market-event-picker-row.is-pinned:not(.is-active) {
    border-left: 3px solid #1576e8;
    padding-left: 8px;
}

.market-event-picker-line {
    gap: 7px;
}

.market-event-picker-line strong {
    flex: 1;
    font-size: 13px;
}

.market-event-picker-line em {
    flex: 0 0 auto;
    font-size: 11px;
    font-style: normal;
    font-weight: 700;
}

.market-event-picker-sub,
.market-event-picker-meta {
    color: var(--text-muted);
    font-size: 10px;
}

.market-event-picker-meta {
    display: flex;
    justify-content: space-between;
    gap: 8px;
}

.market-event-picker-meta span:last-child {
    overflow: hidden;
    text-align: right;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-event-detail {
    gap: 14px;
}

.market-event-decision-surface {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 270px;
    min-width: 0;
    border: 1px solid var(--market-line);
    border-left: 3px solid #f97316;
    background: var(--market-panel);
}

.market-event-decision-main {
    min-width: 0;
    padding: 22px 24px;
}

.market-event-decision-main .market-event-title-row {
    margin-top: 9px;
}

.market-event-decision-main .market-event-title-row h3 {
    font-size: 28px;
}

.market-event-thesis {
    max-width: 720px;
    margin: 9px 0 12px;
    font-size: 13px;
    line-height: 1.65;
}

.market-event-coverage {
    display: grid;
    align-content: start;
    gap: 8px;
    padding: 22px 20px;
    border-left: 1px solid var(--market-line);
    background: var(--market-panel-muted);
}

.market-event-coverage-label,
.market-event-action-label {
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
}

.market-event-coverage > strong {
    color: var(--text-primary);
    font-size: 28px;
    line-height: 1;
}

.market-event-coverage > p {
    margin: 0;
    color: var(--text-secondary);
    font-size: 11px;
    line-height: 1.55;
}

.market-event-coverage-list {
    display: flex;
    flex-wrap: wrap;
    gap: 5px;
    padding-top: 3px;
}

.market-event-coverage-item {
    display: inline-flex;
    align-items: center;
    min-height: 21px;
    padding: 0 7px;
    border: 1px solid var(--market-line);
    border-radius: 999px;
    font-size: 10px;
    line-height: 1;
}

.market-event-coverage-item.is-available {
    border-color: rgba(18, 163, 102, 0.24);
    background: rgba(18, 163, 102, 0.08);
    color: var(--market-down);
}

.market-event-coverage-item.is-unavailable {
    color: var(--text-muted);
}

.market-event-quick-facts {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    margin-top: 17px;
    border-top: 1px solid var(--market-line);
}

.market-event-quick-fact {
    display: grid;
    gap: 4px;
    min-width: 0;
    padding: 12px 13px 0 0;
}

.market-event-quick-fact + .market-event-quick-fact {
    padding-left: 13px;
    border-left: 1px solid var(--market-line);
}

.market-event-quick-fact span,
.market-event-quick-fact small {
    overflow: hidden;
    color: var(--text-muted);
    font-size: 10px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-event-quick-fact strong {
    overflow: hidden;
    color: var(--text-primary);
    font-size: 14px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-event-quick-fact strong.is-up { color: #dc2626; }
.market-event-quick-fact strong.is-down { color: var(--market-down); }

.market-event-actionbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 18px;
    min-height: 70px;
    padding: 13px 16px;
    border-top: 1px solid var(--market-line);
    border-bottom: 1px solid var(--market-line);
    background: transparent;
}

.market-event-actionbar > div:first-child {
    display: grid;
    min-width: 0;
    gap: 3px;
}

.market-event-actionbar strong {
    font-size: 13px;
}

.market-event-actionbar small {
    overflow: hidden;
    color: var(--text-secondary);
    font-size: 11px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-event-action-buttons {
    display: flex;
    flex: 0 0 auto;
    flex-wrap: wrap;
    justify-content: flex-end;
    gap: 8px;
}

.market-event-action-buttons .market-command-btn {
    min-height: 32px;
    padding: 0 11px;
    font-size: 12px;
}

.market-event-view-tabs {
    display: flex;
    gap: 0;
    border-bottom: 1px solid var(--market-line);
}

.market-event-view-tabs button {
    min-width: 104px;
    height: 38px;
    padding: 0 14px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    color: var(--text-secondary);
    font: inherit;
    font-size: 13px;
    cursor: pointer;
}

.market-event-view-tabs button:hover {
    color: var(--text-primary);
}

.market-event-view-tabs button.active {
    border-bottom-color: #1576e8;
    color: #1576e8;
    font-weight: 700;
}

.market-event-view {
    display: none;
}

.market-event-view.active {
    display: grid;
    gap: 14px;
}

[data-event-view-panel="evidence"].active {
    grid-template-columns: minmax(0, 1.1fr) minmax(300px, 0.9fr);
}

.market-event-surface {
    min-width: 0;
    padding: 18px 20px;
    border: 1px solid var(--market-line);
    background: var(--market-panel);
}

.market-event-surface .market-section-head {
    margin-bottom: 14px;
}

.market-event-observation {
    display: grid;
    border-top: 1px solid var(--market-line);
}

.market-event-observation-row {
    display: grid;
    grid-template-columns: 78px minmax(0, 1fr);
    gap: 6px 12px;
    align-items: baseline;
    min-height: 58px;
    padding: 10px 0;
    border-bottom: 1px solid var(--market-line);
}

.market-event-observation-row:last-child {
    border-bottom: 0;
}

.market-event-observation-row > span {
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-observation-row strong {
    font-size: 13px;
}

.market-event-observation-row small {
    grid-column: 2;
    color: var(--text-secondary);
    font-size: 11px;
    line-height: 1.5;
}

.market-event-timeline-item {
    min-height: 60px;
}

.market-event-history-panel {
    padding-bottom: 16px;
}

.market-event-similar-summary {
    display: grid;
    gap: 12px;
    margin-bottom: 16px;
    color: var(--text-secondary);
    font-size: 12px;
}

.market-event-similar-summary-head {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px 18px;
}

.market-event-similar-summary strong {
    color: var(--text-primary);
    font-size: 16px;
}

.market-event-similar-stat-grid {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 8px;
}

.market-event-similar-stat-grid > div {
    display: grid;
    gap: 4px;
    min-height: 48px;
    padding: 8px 10px;
    border: 1px solid var(--market-line);
    border-radius: 7px;
    background: var(--market-bg-alt, rgba(15, 23, 42, 0.025));
}

.market-event-similar-stat-grid span {
    color: var(--text-muted);
    font-size: 10px;
}

.market-event-similar-stat-grid b {
    color: var(--text-primary);
    font-size: 13px;
}

.market-event-similar-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 18px;
}

.market-event-similar-card {
    min-width: 0;
    padding: 18px 20px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    box-shadow: none;
}

.market-event-similar-card-head,
.market-event-similar-returns {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
}

.market-event-similar-card-head strong,
.market-event-similar-card-head small {
    display: block;
}

.market-event-similar-card-head strong { font-size: 16px; }
.market-event-similar-card-head small,
.market-event-similar-returns span {
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-similar-expand {
    flex: 0 0 auto;
    min-height: 32px;
    padding: 0 12px;
    border: 1px solid rgba(21, 118, 232, 0.22);
    border-radius: 7px;
    color: #1576e8;
    background: rgba(21, 118, 232, 0.06);
    font-size: 12px;
    font-weight: 700;
    cursor: pointer;
    transition: border-color 160ms ease, background 160ms ease, transform 160ms ease;
}

.market-event-similar-expand:hover {
    border-color: rgba(21, 118, 232, 0.48);
    background: rgba(21, 118, 232, 0.11);
    transform: translateY(-1px);
}

.market-event-similar-sequence {
    display: inline-flex;
    margin: 12px 0 2px;
    padding: 5px 9px;
    border-radius: 999px;
    color: #1576e8;
    background: rgba(21, 118, 232, 0.08);
    font-size: 12px;
    font-weight: 700;
}

.market-event-similar-spark {
    display: flex;
    align-items: end;
    gap: 3px;
    height: 54px;
    padding: 8px 10px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: #f8fafc;
}

.market-event-similar-spark i {
    flex: 1;
    min-width: 3px;
    border-radius: 2px 2px 0 0;
    background: #ef4444;
}

.market-event-similar-spark > span {
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-similar-returns {
    justify-content: flex-start;
    margin-top: 14px;
    padding-top: 12px;
    border-top: 1px solid var(--market-line);
}

.market-event-similar-returns > div {
    display: grid;
    gap: 3px;
    min-width: 88px;
}

.market-event-similar-returns strong { font-size: 15px; }
.market-event-similar-chart {
    position: relative;
    height: 286px;
    margin-top: 12px;
    padding: 10px 12px 34px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: linear-gradient(180deg, #fbfdff 0%, #f5f8fb 100%);
    overflow: hidden;
}

.market-event-similar-chart svg {
    display: block;
    width: 100%;
    height: calc(100% - 16px);
    overflow: visible;
}

.market-event-similar-after-zone {
    fill: rgba(21, 118, 232, 0.075);
}

.market-event-similar-wick {
    stroke-width: 1.65;
    vector-effect: non-scaling-stroke;
}

.market-event-similar-candle {
    stroke-width: 1.2;
    vector-effect: non-scaling-stroke;
}

.market-event-similar-candle.is-up { fill: #ef4444; stroke: #dc2626; }
.market-event-similar-candle.is-down { fill: #16a34a; stroke: #15803d; }

.market-event-similar-volume.is-up { fill: rgba(239, 68, 68, 0.46); }
.market-event-similar-volume.is-down { fill: rgba(22, 163, 74, 0.46); }

.market-event-similar-board-marker rect {
    fill: #f97316;
    stroke: rgba(255, 255, 255, 0.8);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.market-event-similar-board-marker line {
    stroke: rgba(249, 115, 22, 0.72);
    stroke-width: 1;
    stroke-dasharray: 2 2;
    vector-effect: non-scaling-stroke;
}

.market-event-similar-board-marker text {
    fill: #fff;
    font-size: 10px;
    font-weight: 700;
    text-anchor: middle;
}

.market-event-similar-anchor-label rect {
    fill: #fff7ed;
    stroke: #f97316;
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.market-event-similar-anchor-label text {
    fill: #ea580c;
    font-size: 10px;
    font-weight: 700;
    text-anchor: middle;
}

.market-event-similar-gridline {
    stroke: rgba(148, 163, 184, 0.3);
    stroke-width: 1;
    stroke-dasharray: 3 4;
    vector-effect: non-scaling-stroke;
}

.market-event-similar-axis-label,
.market-event-similar-date-label,
.market-event-similar-volume-label {
    fill: var(--text-muted);
    font-size: 10px;
}

.market-event-similar-axis-label,
.market-event-similar-volume-label {
    text-anchor: end;
}

.market-event-similar-volume-divider {
    stroke: rgba(148, 163, 184, 0.28);
    stroke-width: 1;
    vector-effect: non-scaling-stroke;
}

.market-event-similar-line {
    fill: none;
    stroke: rgba(21, 118, 232, 0.2);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.market-event-similar-line.is-before { stroke: #94a3b8; }
.market-event-similar-line.is-after { stroke: #16a34a; stroke-width: 2.5; }

.market-event-similar-anchor {
    stroke: #f97316;
    stroke-width: 1.8;
    stroke-dasharray: 5 4;
    vector-effect: non-scaling-stroke;
}

.market-event-similar-anchor-dot {
    fill: #fff;
    stroke: #f97316;
    stroke-width: 2;
}

.market-event-similar-chart-legend {
    position: absolute;
    right: 12px;
    bottom: 8px;
    left: 12px;
    display: flex;
    align-items: center;
    gap: 14px;
    color: var(--text-muted);
    font-size: 10px;
}

.market-event-similar-chart-legend span {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    white-space: nowrap;
}

.market-event-similar-chart-legend i {
    display: inline-block;
    width: 9px;
    height: 9px;
    border-radius: 3px;
}

.market-event-similar-chart-legend i.is-board { background: #f97316; }
.market-event-similar-chart-legend i.is-anchor {
    width: 2px;
    border-radius: 0;
    background: #f97316;
}
.market-event-similar-chart-legend i.is-after {
    border: 1px solid rgba(21, 118, 232, 0.22);
    background: rgba(21, 118, 232, 0.11);
}

.market-event-similar-chart-legend small {
    margin-left: auto;
    color: var(--text-muted);
    font-size: 10px;
}

.market-event-similar-chart-empty {
    display: grid;
    place-items: center;
    color: var(--text-muted);
    font-size: 11px;
}

[data-theme="dark"] .market-event-similar-chart {
    background: linear-gradient(180deg, rgba(30, 41, 59, 0.72) 0%, rgba(15, 23, 42, 0.72) 100%);
}

[data-theme="dark"] .market-event-similar-anchor-label rect {
    fill: rgba(124, 45, 18, 0.75);
}

.market-similar-modal-open {
    overflow: hidden;
}

.market-event-similar-modal {
    position: fixed;
    inset: 0;
    z-index: 1200;
    display: none;
    place-items: center;
    padding: 28px;
}

.market-event-similar-modal.is-open {
    display: grid;
}

.market-event-similar-modal-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.68);
    backdrop-filter: blur(4px);
}

.market-event-similar-modal-dialog {
    position: relative;
    width: min(1240px, 96vw);
    max-height: 92vh;
    padding: 22px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    box-shadow: 0 28px 80px rgba(15, 23, 42, 0.38);
    overflow: auto;
}

.market-event-similar-modal-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 18px;
    margin-bottom: 16px;
}

.market-event-similar-modal-head span,
.market-event-similar-modal-head small {
    color: var(--text-muted);
    font-size: 12px;
}

.market-event-similar-modal-head h3 {
    margin: 4px 0;
    color: var(--text-primary);
    font-size: 22px;
}

.market-event-similar-modal-close {
    flex: 0 0 auto;
    width: 38px;
    height: 38px;
    border: 1px solid var(--market-line);
    border-radius: 50%;
    color: var(--text-secondary);
    background: var(--market-bg-alt, rgba(148, 163, 184, 0.08));
    font-size: 25px;
    line-height: 1;
    cursor: pointer;
}

.market-event-similar-modal-body .market-event-similar-chart.is-expanded {
    height: min(58vh, 520px);
    margin-top: 0;
}

.market-event-similar-modal-returns {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
    margin-top: 14px;
}

.market-event-similar-modal-returns > div {
    display: grid;
    gap: 5px;
    padding: 12px 14px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-bg-alt, rgba(148, 163, 184, 0.06));
}

.market-event-similar-modal-returns span {
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-similar-modal-returns strong {
    font-size: 17px;
}

.market-event-similar-disclosure {
    margin: 16px 0 0;
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.6;
}

@media (max-width: 1180px) {
    .market-event-similar-stat-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

@media (max-width: 760px) {
    .market-event-similar-stat-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .market-event-similar-card { padding: 14px; }
    .market-event-similar-chart { height: 240px; padding-inline: 4px; }
    .market-event-similar-chart-legend { gap: 8px; }
    .market-event-similar-chart-legend small { display: none; }
    .market-event-similar-modal { padding: 10px; }
    .market-event-similar-modal-dialog { width: 100%; padding: 15px; }
    .market-event-similar-modal-body .market-event-similar-chart.is-expanded { height: 58vh; }
    .market-event-similar-modal-returns { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}


@media (max-width: 1180px) {
    .market-event-content { grid-template-columns: 1fr; }
    .market-event-picker { position: static; max-height: none; }
    .market-event-picker-body { max-height: 320px; }
}

@media (max-width: 900px) {
    .market-event-decision-surface { grid-template-columns: 1fr; }
    .market-event-coverage { border-top: 1px solid var(--market-line); border-left: 0; }
    [data-event-view-panel="evidence"].active { grid-template-columns: 1fr; }
}

@media (max-width: 640px) {
    .market-event-decision-main { padding: 18px; }
    .market-event-coverage { padding: 18px; }
    .market-event-decision-main .market-event-title-row h3 { font-size: 24px; }
    .market-event-quick-facts { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    .market-event-quick-fact:nth-child(3) { border-left: 0; padding-left: 0; }
    .market-event-quick-fact:nth-child(n + 3) { padding-top: 12px; }
    .market-event-quick-fact:nth-child(5) { border-left: 1px solid var(--market-line); padding-left: 13px; }
    .market-event-actionbar { display: grid; align-items: start; }
    .market-event-actionbar small { white-space: normal; }
    .market-event-action-buttons { justify-content: flex-start; }
    .market-event-view-tabs { overflow-x: auto; }
    .market-event-view-tabs button { min-width: 96px; padding: 0 10px; }
    .market-event-surface { padding: 16px; }
    .market-event-observation-row { grid-template-columns: 1fr; gap: 4px; }
    .market-event-observation-row small { grid-column: auto; }
}
.market-event-attribution-surface {
    grid-column: 1 / -1;
    border-top: 3px solid #d97706;
}

.market-event-attribution-surface .market-section-head > div {
    display: grid;
    gap: 3px;
}

.market-event-attribution-status {
    display: inline-flex;
    align-items: center;
    min-height: 24px;
    padding: 0 8px;
    border: 1px solid var(--market-line);
    border-radius: 999px;
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
}

.market-event-attribution-status.is-provisional {
    border-color: rgba(217, 119, 6, 0.35);
    background: rgba(217, 119, 6, 0.1);
    color: #b45309;
}

.market-event-attribution-status.is-post-event {
    border-color: rgba(21, 118, 232, 0.28);
    background: rgba(21, 118, 232, 0.08);
    color: #0b5fd0;
}

.market-event-attribution-summary {
    margin-bottom: 12px;
    padding: 10px 12px;
    border-left: 3px solid #d97706;
    background: rgba(217, 119, 6, 0.06);
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.55;
}

.market-event-attribution-list {
    display: grid;
    gap: 8px;
}

.market-event-note-card {
    display: grid;
    gap: 7px;
    padding: 12px 13px;
    border: 1px solid var(--market-line);
    border-left: 3px solid #d97706;
    background: var(--market-panel);
}

.market-event-note-card.is-post-event {
    border-left-color: #1576e8;
    background: rgba(21, 118, 232, 0.035);
}

.market-event-note-meta,
.market-event-note-foot {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px 10px;
    color: var(--text-muted);
    font-size: 10px;
}

.market-event-note-timing {
    color: #b45309;
    font-weight: 700;
}

.market-event-note-card.is-post-event .market-event-note-timing {
    color: #0b5fd0;
}

.market-event-note-card > strong {
    color: var(--text-primary);
    font-size: 13px;
    line-height: 1.45;
}

.market-event-note-card > p {
    display: -webkit-box;
    overflow: hidden;
    margin: 0;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.6;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
}

.market-event-note-foot {
    justify-content: space-between;
    padding-top: 2px;
}

.market-event-note-link {
    color: #1576e8;
    font-size: 11px;
    font-weight: 700;
    text-decoration: none;
}

.market-event-note-link:hover {
    text-decoration: underline;
}

.market-event-note-link.is-muted {
    color: var(--text-muted);
    font-weight: 400;
}

@media (max-width: 640px) {
    .market-event-note-foot { align-items: flex-start; flex-direction: column; }
}
.market-event-interpretation-surface {
    border-top: 3px solid #1576e8;
}

.market-event-interpretation-surface .market-section-head > div {
    display: grid;
    gap: 3px;
}

.market-event-interpretation-summary {
    margin-bottom: 14px;
    padding: 11px 13px;
    border-left: 3px solid #1576e8;
    background: rgba(21, 118, 232, 0.06);
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.6;
}

.market-event-interpretation-grid {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    border-top: 1px solid var(--market-line);
}

.market-event-interpretation-section {
    display: grid;
    min-width: 0;
    gap: 7px;
    padding: 14px 15px 12px 0;
}

.market-event-interpretation-section + .market-event-interpretation-section {
    padding-left: 15px;
    border-left: 1px solid var(--market-line);
}

.market-event-interpretation-section > span {
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-interpretation-section > strong {
    color: var(--text-primary);
    font-size: 14px;
    line-height: 1.45;
}

.market-event-interpretation-section > p,
.market-event-interpretation-section > small {
    margin: 0;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.55;
}

.market-event-interpretation-section > small {
    color: var(--text-muted);
    font-size: 11px;
}

.market-event-interpretation-section.is-driver > strong {
    color: var(--market-hot, #e74c3c);
}

.market-event-announcement-list {
    margin: 8px 0 4px;
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.market-event-announcement-item {
    display: flex;
    align-items: baseline;
    gap: 8px;
    padding: 4px 8px;
    background: var(--market-bg-alt, rgba(0,0,0,0.02));
    border-radius: 4px;
    border-left: 3px solid var(--market-hot, #e74c3c);
}

.market-event-ann-date {
    font-size: 11px;
    color: var(--text-muted);
    flex-shrink: 0;
    min-width: 40px;
}

.market-event-ann-type {
    font-size: 11px;
    color: var(--market-hot, #e74c3c);
    font-weight: 600;
    flex-shrink: 0;
    min-width: 60px;
}

.market-event-ann-title {
    font-size: 12px;
    color: var(--text-primary);
    line-height: 1.5;
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    word-break: break-word;
    white-space: normal;
}

.market-event-ann-collapsed {
    font-size: 11px;
    color: var(--text-muted);
    padding: 2px 8px 0;
}

.market-event-disclosure {
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px dashed var(--market-border, rgba(0,0,0,0.08));
    font-size: 11px;
    line-height: 1.5;
    color: var(--text-muted);
}

/* AI 精读区块 */
.market-event-ai-interpretation {
    margin: 0 0 12px;
    padding: 14px 16px;
    border: 1px solid var(--market-accent, #1576e8);
    border-left: 4px solid var(--market-accent, #1576e8);
    border-radius: 8px;
    background: var(--market-panel, #ffffff);
}

.market-event-ai-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}

.market-event-ai-head strong {
    font-size: 14px;
    color: var(--market-accent, #1576e8);
}

.market-event-ai-meta {
    font-size: 11px;
    color: var(--text-muted);
}

.market-event-ai-headline {
    font-size: 13px;
    font-weight: 600;
    color: var(--text-primary);
    line-height: 1.6;
    margin: 0 0 10px;
}

/* Shown only when the selected session had no snapshot and the backend served
   the newest one that did. A data note, not an error and not instructions. */
.market-event-ai-session {
    margin: 0 0 10px;
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 11px;
    line-height: 1.5;
    color: var(--text-secondary, #555);
    background: var(--market-bg-alt, rgba(0,0,0,0.03));
    border-left: 3px solid var(--market-border, rgba(0,0,0,0.12));
}

.market-event-ai-drivers {
    display: flex;
    flex-direction: column;
    gap: 8px;
    margin-bottom: 10px;
}

.market-event-ai-driver {
    padding: 8px 10px;
    border-radius: 6px;
    background: var(--market-bg-alt, rgba(0,0,0,0.02));
}

.market-event-ai-driver strong {
    display: block;
    font-size: 13px;
    color: var(--text-primary);
    line-height: 1.5;
}

.market-event-ai-driver p {
    margin: 4px 0 0;
    font-size: 12px;
    color: var(--text-secondary, #555);
    line-height: 1.5;
}

.market-event-ai-confidence {
    display: inline-block;
    margin-right: 6px;
    padding: 1px 6px;
    border-radius: 3px;
    font-size: 11px;
    font-weight: 600;
    color: #ffffff;
    background: var(--market-accent, #1576e8);
}

.market-event-ai-rating {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-bottom: 10px;
}

.market-event-ai-tag {
    padding: 2px 8px;
    border-radius: 4px;
    font-size: 11px;
    font-weight: 600;
    background: var(--market-bg-alt, rgba(0,0,0,0.04));
    color: var(--text-secondary, #555);
}

.market-event-ai-tag.is-level {
    background: var(--market-hot, #e74c3c);
    color: #ffffff;
}

.market-event-ai-rank {
    display: inline-block;
    margin-right: 6px;
    font-size: 11px;
    font-weight: 700;
    color: var(--market-accent, #1576e8);
}

.market-event-ai-row {
    margin-top: 8px;
}

.market-event-ai-row span {
    display: inline-block;
    font-size: 11px;
    font-weight: 600;
    color: var(--market-accent, #1576e8);
    margin-right: 6px;
}

.market-event-ai-row p {
    display: inline;
    font-size: 12px;
    color: var(--text-primary);
    line-height: 1.6;
}

.market-event-ai-row ul {
    display: inline;
    margin: 0;
    padding: 0;
    list-style: none;
}

.market-event-ai-row ul li {
    display: block;
    margin-top: 3px;
    padding-left: 14px;
    position: relative;
    font-size: 12px;
    color: var(--text-primary);
    line-height: 1.5;
}

.market-event-ai-row ul li::before {
    content: "·";
    position: absolute;
    left: 4px;
    color: var(--market-accent, #1576e8);
}

.market-event-ai-state {
    padding: 12px;
    border-radius: 6px;
    font-size: 12px;
    color: var(--text-secondary, #555);
    background: var(--market-bg-alt, rgba(0,0,0,0.02));
}

.market-event-ai-state.is-error {
    color: var(--market-hot, #e74c3c);
}

/* The 精读 run crosses two MCPs, so the waiting state has to read as *working*
   rather than *frozen*. An indeterminate bar plus the elapsed counter does that
   without claiming a percentage the client cannot actually know. */
.market-event-ai-state.is-running {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    justify-content: space-between;
}

.market-event-ai-progress {
    position: relative;
    flex: 1 0 100%;
    height: 3px;
    overflow: hidden;
    border-radius: 2px;
    background: var(--market-border, rgba(0,0,0,0.08));
}

.market-event-ai-progress::after {
    content: "";
    position: absolute;
    inset: 0 auto 0 0;
    width: 35%;
    border-radius: 2px;
    background: var(--market-accent, #1576e8);
    animation: market-event-ai-progress-slide 1.4s ease-in-out infinite;
}

@keyframes market-event-ai-progress-slide {
    0% { transform: translateX(-100%); }
    100% { transform: translateX(320%); }
}

@media (prefers-reduced-motion: reduce) {
    .market-event-ai-progress::after {
        animation: none;
        width: 100%;
        opacity: 0.5;
    }
}

.market-event-ai-foot {
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px dashed var(--market-border, rgba(0,0,0,0.08));
    font-size: 11px;
    color: var(--text-muted);
}

.market-event-interpretation-section.is-strategy {
    background: var(--market-bg-alt, rgba(0,0,0,0.02));
    border-radius: 6px;
    padding: 12px 15px 10px 15px;
}

.market-event-interpretation-section.is-strategy > strong {
    color: var(--market-accent, #1576e8);
}

.market-event-interpretation-section.is-risk > strong {
    color: var(--market-warn, #f39c12);
}

.market-event-interpretation-tag {
    display: inline-block;
    padding: 1px 7px;
    margin-top: 2px;
    border-radius: 3px;
    font-size: 11px;
    color: var(--text-secondary);
    background: var(--market-bg-alt, rgba(0,0,0,0.04));
    border: 1px solid var(--market-line, rgba(0,0,0,0.06));
}

@media (max-width: 900px) {
    .market-event-interpretation-grid { grid-template-columns: 1fr; }
    .market-event-interpretation-section { padding: 12px 0; }
    .market-event-interpretation-section + .market-event-interpretation-section {
        padding-left: 0;
        border-top: 1px solid var(--market-line);
        border-left: 0;
    }
}
.market-event-ai-verdict {
    display: flex;
    justify-content: space-between;
    align-items: flex-start;
    gap: 18px;
    margin: 0 0 14px;
    padding: 12px 14px;
    border-radius: 7px;
    background: linear-gradient(90deg, rgba(21, 118, 232, 0.08), rgba(21, 118, 232, 0.01));
}

.market-event-ai-verdict > div { min-width: 0; }

.market-event-ai-verdict > div > span,
.market-event-ai-block-head span,
.market-event-ai-quality span,
.market-event-ai-structure-grid span {
    font-size: 11px;
    color: var(--text-muted);
}

.market-event-ai-verdict h3 {
    margin: 3px 0 4px;
    font-size: 16px;
    line-height: 1.45;
    color: var(--text-primary);
}

.market-event-ai-verdict p {
    margin: 0;
    font-size: 13px;
    line-height: 1.65;
    color: var(--text-secondary, #555);
}

.market-event-ai-verdict .market-event-ai-rating {
    justify-content: flex-end;
    margin: 1px 0 0;
    max-width: 42%;
}

.market-event-ai-block {
    margin: 14px 0 0;
}

.market-event-ai-block-head,
.market-event-ai-driver-head,
.market-event-ai-quality-head {
    display: flex;
    align-items: center;
    gap: 7px;
}

.market-event-ai-block-head {
    justify-content: space-between;
    margin-bottom: 7px;
}

.market-event-ai-block-head h4 {
    margin: 0;
    font-size: 13px;
    color: var(--text-primary);
}

.market-event-ai-driver {
    border: 1px solid var(--market-line, rgba(0,0,0,0.06));
}

.market-event-ai-driver-head {
    margin-bottom: 5px;
}

.market-event-ai-driver-type {
    font-size: 11px;
    color: var(--text-secondary, #555);
}

.market-event-ai-refs {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-top: 7px;
}

.market-event-ai-refs span {
    padding: 2px 6px;
    border-radius: 3px;
    background: rgba(21, 118, 232, 0.09);
    color: var(--market-accent, #1576e8);
    font-size: 11px;
}

.market-event-ai-web-refs {
    margin: 7px 0 0;
    padding-left: 17px;
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.5;
}

.market-event-ai-local-evidence,
.market-event-ai-source-list {
    margin: 8px 0 0;
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.55;
}

.market-event-ai-local-evidence span,
.market-event-ai-source-list > span {
    margin-right: 4px;
    color: var(--text-secondary, #555);
    font-weight: 600;
}

.market-event-ai-source-list ol {
    margin: 3px 0 0;
    padding-left: 18px;
}

.market-event-ai-structure-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 7px;
}

.market-event-ai-structure-grid article {
    padding: 9px 10px;
    border-radius: 6px;
    background: var(--market-bg-alt, rgba(0,0,0,0.02));
}

.market-event-ai-structure-grid p {
    margin: 3px 0 0;
    color: var(--text-primary);
    font-size: 12px;
    line-height: 1.55;
}

.market-event-ai-structure-grid ul {
    margin: 4px 0 0;
    padding-left: 15px;
    color: var(--text-primary);
    font-size: 12px;
    line-height: 1.55;
}

.market-event-ai-structure-grid li + li {
    margin-top: 3px;
}

.market-event-ai-quality {
    margin-top: 14px;
    padding: 11px 12px;
    border: 1px solid rgba(243, 156, 18, 0.23);
    border-radius: 7px;
    background: rgba(243, 156, 18, 0.045);
}

.market-event-ai-quality-head {
    justify-content: space-between;
}

.market-event-ai-quality-head strong {
    display: block;
    margin-top: 2px;
    color: var(--text-primary);
    font-size: 14px;
}

.market-event-ai-watchpoint,
.market-event-ai-risks {
    margin-top: 9px;
}

.market-event-ai-watchpoint > span,
.market-event-ai-risks > span {
    color: var(--market-accent, #1576e8);
    font-size: 11px;
    font-weight: 600;
}

.market-event-ai-watchpoint p,
.market-event-ai-risks ul {
    margin: 3px 0 0;
    color: var(--text-primary);
    font-size: 12px;
    line-height: 1.55;
}

.market-event-ai-risks ul {
    padding-left: 17px;
}

.market-event-ai-gaps,
.market-event-ai-ledger {
    margin-top: 10px;
}

.market-event-ai-gaps summary,
.market-event-ai-ledger summary {
    cursor: pointer;
    color: var(--text-secondary, #555);
    font-size: 12px;
    font-weight: 600;
}

.market-event-ai-gaps ul {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 7px;
    margin: 8px 0 0;
    padding: 0;
    list-style: none;
}

.market-event-ai-gaps li {
    padding: 8px 9px;
    border-radius: 5px;
    background: rgba(255,255,255,0.6);
}

.market-event-ai-gaps li strong {
    color: var(--market-warn, #f39c12);
    font-size: 12px;
}

.market-event-ai-gaps li p {
    margin: 3px 0;
    color: var(--text-secondary, #555);
    font-size: 11px;
    line-height: 1.45;
}

.market-event-ai-gaps li small {
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.45;
}

.market-event-ai-complete,
.market-event-ai-empty {
    margin: 9px 0 0;
    color: var(--text-muted);
    font-size: 12px;
}

.market-event-ai-ledger > div {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 6px;
    margin-top: 8px;
}

.market-event-ai-ledger article {
    position: relative;
    min-height: 54px;
    padding: 7px 8px;
    border-radius: 5px;
    background: var(--market-bg-alt, rgba(0,0,0,0.02));
}

.market-event-ai-ledger article.is-missing {
    opacity: 0.55;
}

.market-event-ai-ledger article > span {
    display: inline-block;
    margin-right: 5px;
    color: var(--market-accent, #1576e8);
    font-size: 11px;
    font-weight: 700;
}

.market-event-ai-ledger article strong {
    font-size: 11px;
    color: var(--text-primary);
}

.market-event-ai-ledger article em {
    margin-left: 4px;
    color: var(--market-accent, #1576e8);
    font-size: 10px;
    font-style: normal;
}

.market-event-ai-ledger article small {
    display: block;
    margin-top: 4px;
    color: var(--text-muted);
    font-size: 10px;
    line-height: 1.35;
}

@media (max-width: 900px) {
    .market-event-ai-verdict {
        flex-direction: column;
        gap: 8px;
    }

    .market-event-ai-verdict .market-event-ai-rating {
        justify-content: flex-start;
        max-width: none;
    }

    .market-event-ai-structure-grid,
    .market-event-ai-gaps ul,
    .market-event-ai-ledger > div {
        grid-template-columns: 1fr;
    }
}

/* ==== Market pulse dashboard (intraday redesign) ==== */

.market-score-delta,
.market-score-percentile {
    margin-top: 4px;
    font-size: 12px;
    color: var(--text-muted);
}

.market-score-delta.is-up { color: var(--market-up); }
.market-score-delta.is-down { color: var(--market-down); }

.market-live-tag {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 8px;
    border-radius: 999px;
    background: rgba(220, 38, 38, 0.08);
    color: var(--market-up);
    font-size: 11px;
    font-weight: 700;
}

.market-live-tag::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: var(--market-up);
    animation: marketLivePulse 1.6s ease-in-out infinite;
}

@keyframes marketLivePulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.25; }
}

.market-state-badge.is-live {
    border-color: rgba(220, 38, 38, 0.35);
    background: var(--market-up-soft);
    color: var(--market-up);
}

.market-cycle-banner {
    display: grid;
    gap: 8px;
    margin-top: 14px;
}

.market-cycle-main {
    display: flex;
    align-items: center;
    gap: 14px;
    flex-wrap: wrap;
    padding: 12px 16px;
    border: 1px solid var(--market-line);
    border-left: 4px solid #64748b;
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.market-cycle-main.is-ice { border-left-color: #38bdf8; background: rgba(56, 189, 248, 0.07); }
.market-cycle-main.is-ignition { border-left-color: #f59e0b; background: rgba(245, 158, 11, 0.08); }
.market-cycle-main.is-fermenting { border-left-color: #ef4444; background: rgba(239, 68, 68, 0.06); }
.market-cycle-main.is-climax { border-left-color: #dc2626; background: rgba(220, 38, 38, 0.09); }
.market-cycle-main.is-divergence { border-left-color: #b45309; background: var(--market-amber-soft); }
.market-cycle-main.is-ebbing { border-left-color: #047857; background: var(--market-down-soft); }
.market-cycle-main.is-unknown {
    border-left-color: #94a3b8;
    background: repeating-linear-gradient(
        -45deg,
        rgba(148, 163, 184, 0.10),
        rgba(148, 163, 184, 0.10) 6px,
        rgba(148, 163, 184, 0.04) 6px,
        rgba(148, 163, 184, 0.04) 12px
    );
}

.market-cycle-stage {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

.market-cycle-label {
    color: var(--text-muted);
    font-size: 12px;
}

.market-cycle-stage strong {
    font-size: 20px;
    font-weight: 800;
}

.market-cycle-main.is-ice .market-cycle-stage strong { color: #0284c7; }
.market-cycle-main.is-ignition .market-cycle-stage strong { color: var(--market-amber); }
.market-cycle-main.is-fermenting .market-cycle-stage strong { color: var(--market-up); }
.market-cycle-main.is-climax .market-cycle-stage strong { color: #dc2626; }
.market-cycle-main.is-divergence .market-cycle-stage strong { color: var(--market-amber); }
.market-cycle-main.is-ebbing .market-cycle-stage strong { color: var(--market-down); }
.market-cycle-main.is-unknown .market-cycle-stage strong {
    color: #64748b;
    font-weight: 700;
}

.market-cycle-chips {
    display: flex;
    gap: 6px;
    flex-wrap: wrap;
}

.market-cycle-chip {
    padding: 3px 9px;
    border: 1px solid rgba(180, 83, 9, 0.3);
    border-radius: 999px;
    background: var(--market-amber-soft);
    color: var(--market-amber);
    font-size: 12px;
}

.market-pulse-help {
    margin-top: 14px;
}

.market-component-bars .market-component-row {
    display: grid;
    grid-template-columns: minmax(82px, 110px) minmax(60px, 1fr) 40px 46px 44px;
    align-items: center;
    gap: 10px;
    padding: 4px 6px;
    margin: 0 -6px;
    border: 0;
    border-radius: 6px;
    background: transparent;
    font: inherit;
    font-size: 12px;
    text-align: left;
    cursor: pointer;
}

.market-component-bars .market-component-row:hover,
.market-component-bars .market-component-row:focus-visible {
    background: var(--market-panel-muted);
    outline: none;
}

.market-component-bars .market-component-row.is-open {
    background: var(--market-panel-muted);
}

.market-comp-label {
    overflow: hidden;
    color: var(--text-secondary);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-comp-score {
    color: var(--text-primary);
    text-align: right;
    font-size: 13px;
}

.market-comp-delta {
    text-align: right;
    color: var(--text-muted);
    font-size: 11px;
}

.market-comp-delta.is-up { color: var(--market-up); }
.market-comp-delta.is-down { color: var(--market-down); }

.market-comp-pct {
    text-align: right;
    color: var(--text-muted);
    font-size: 11px;
}

.market-component-detail {
    margin-top: 10px;
    padding: 12px 14px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.market-component-detail-inner {
    display: grid;
    gap: 10px;
    font-size: 13px;
}

.market-component-detail-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
}

.market-component-detail-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
}

.market-component-detail-grid > div {
    padding: 8px 10px;
    border-radius: 6px;
    background: var(--market-panel-muted);
}

.market-component-detail-grid span {
    display: block;
    color: var(--text-muted);
    font-size: 11px;
}

.market-component-detail-grid strong {
    font-size: 15px;
}

.market-component-detail p {
    margin: 0;
    color: var(--text-secondary);
}

.market-promotion-list {
    display: grid;
    gap: 6px;
}

.market-promotion-item {
    display: grid;
    grid-template-columns: 90px 1fr 52px 110px;
    align-items: center;
    gap: 8px;
    font-size: 12px;
}

.market-promotion-item small {
    color: var(--text-muted);
}

.market-promotion-item.is-low-sample {
    opacity: 0.55;
}

/* ==== Theme-first ladder ==== */

.market-plate-groups {
    display: grid;
    gap: 10px;
    margin-top: 14px;
}

.market-plate-card {
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    overflow: hidden;
}

.market-plate-card.is-expanded {
    border-color: #1576e8;
}

.market-plate-card.is-misc {
    opacity: 0.85;
}

.market-plate-card-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    padding: 10px 14px;
    cursor: pointer;
    user-select: none;
}

.market-plate-card-head:hover {
    background: var(--market-panel-muted);
}

.market-plate-title {
    display: flex;
    align-items: center;
    gap: 8px;
    min-width: 150px;
}

.market-plate-title strong {
    font-size: 15px;
}

.market-plate-stats {
    display: flex;
    align-items: center;
    gap: 6px;
    flex-wrap: wrap;
}

.market-plate-step-chip {
    padding: 2px 8px;
    border-radius: 999px;
    background: var(--market-panel-muted);
    border: 1px solid var(--market-line);
    color: var(--text-secondary);
    font-size: 11px;
    white-space: nowrap;
}

.market-plate-step-chip.is-height {
    border-color: rgba(220, 38, 38, 0.4);
    background: var(--market-up-soft);
    color: var(--market-up);
    font-weight: 700;
}

.market-plate-metrics {
    display: flex;
    align-items: center;
    gap: 14px;
    color: var(--text-muted);
    font-size: 12px;
}

.market-plate-metrics b {
    color: var(--text-primary);
}

.market-plate-caret {
    font-style: normal;
    color: var(--text-muted);
}

.market-plate-stage {
    padding: 2px 8px;
    border-radius: 999px;
    font-size: 11px;
    font-weight: 700;
    border: 1px solid var(--market-line);
    color: var(--text-secondary);
    white-space: nowrap;
}

.market-plate-stage.is-climax { border-color: rgba(220,38,38,.4); background: var(--market-up-soft); color: #dc2626; }
.market-plate-stage.is-accelerating { border-color: rgba(239,68,68,.35); background: rgba(239,68,68,.07); color: var(--market-up); }
.market-plate-stage.is-igniting { border-color: rgba(245,158,11,.4); background: var(--market-amber-soft); color: var(--market-amber); }
.market-plate-stage.is-diverging { border-color: rgba(180,83,9,.4); background: var(--market-amber-soft); color: var(--market-amber); }
.market-plate-stage.is-ebbing { border-color: rgba(4,120,87,.35); background: var(--market-down-soft); color: var(--market-down); }

.market-plate-card-body {
    border-top: 1px solid var(--market-line);
    padding: 8px 14px 12px;
}

.market-plate-stock-head,
.market-plate-stock {
    display: grid;
    grid-template-columns: minmax(110px, 1.2fr) 44px 76px 72px 60px 52px 72px minmax(90px, 1fr);
    gap: 8px;
    align-items: center;
    font-size: 12px;
}

.market-plate-stock-head {
    padding: 4px 8px;
    color: var(--text-muted);
    font-size: 11px;
}

.market-plate-stock {
    padding: 7px 8px;
    border-radius: 6px;
    cursor: pointer;
}

.market-plate-stock:hover {
    background: var(--market-panel-muted);
}

.market-plate-stock-reason {
    color: var(--text-secondary);
    font-size: 11px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-plate-stock + .market-plate-stock {
    border-top: 1px dashed var(--market-line);
}

.market-plate-stock-name {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}

.market-plate-stock-name small {
    color: var(--text-muted);
}

.market-plate-stock-step {
    color: var(--market-up);
}

.market-plate-stock.is-promoted .market-plate-stock-name strong::after {
    content: '晋';
    margin-left: 6px;
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--market-up-soft);
    color: var(--market-up);
    font-size: 10px;
}

/* Compact, scan-first ladder layout */
#market-promotion-strip {
    grid-template-columns: repeat(7, minmax(0, 1fr));
    margin: 18px 0 22px;
}

#market-promotion-strip .market-metric-cell {
    min-height: 76px;
    padding: 12px 14px;
}

#market-promotion-strip .market-metric-cell:nth-child(-n+2) {
    background: var(--market-panel-muted);
}

#market-promotion-strip .market-metric-cell span {
    color: var(--text-secondary);
    font-size: 11px;
}

#market-promotion-strip .market-metric-cell strong {
    margin-top: 6px;
    font-size: 20px;
}

.market-ladder-intro {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    margin: 2px 0 10px;
}

.market-ladder-intro > div {
    display: grid;
    gap: 3px;
}

.market-ladder-intro-kicker {
    color: #1576e8;
    font-size: 10px;
    font-weight: 800;
    letter-spacing: .08em;
}

.market-ladder-intro strong {
    font-size: 17px;
}

.market-ladder-intro small,
.market-ladder-intro-meta {
    color: var(--text-muted);
    font-size: 11px;
}

.market-ladder-intro-meta {
    padding-bottom: 3px;
    white-space: nowrap;
}

.market-plate-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
    gap: 12px;
}

.market-plate-grid .market-plate-card {
    min-width: 0;
}

.market-plate-grid .market-plate-card-head {
    display: grid;
    grid-template-columns: 28px minmax(0, 1.35fr) minmax(90px, .95fr) 70px minmax(138px, 1.1fr);
    align-items: center;
    gap: 10px;
    min-height: 82px;
    padding: 12px 14px;
}

.market-plate-rank {
    align-self: start;
    padding-top: 2px;
    color: var(--text-muted);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.market-plate-title {
    display: grid;
    gap: 5px;
    min-width: 0;
}

.market-plate-title-line {
    display: flex;
    align-items: center;
    gap: 7px;
    min-width: 0;
}

.market-plate-title strong {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 16px;
}

.market-plate-title small,
.market-plate-lead span,
.market-plate-lead small,
.market-plate-height span {
    color: var(--text-muted);
    font-size: 10px;
}

.market-plate-title small {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-plate-lead {
    display: grid;
    min-width: 0;
    gap: 2px;
}

.market-plate-lead strong {
    overflow: hidden;
    color: var(--text-primary);
    font-size: 12px;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-plate-height {
    display: grid;
    justify-items: center;
    gap: 1px;
    padding-left: 9px;
    border-left: 1px solid var(--market-line);
}

.market-plate-height strong {
    color: var(--market-up);
    font-size: 23px;
    line-height: 1;
}

.market-plate-height span {
    text-align: center;
    white-space: nowrap;
}

.market-plate-grid .market-plate-metrics {
    justify-content: flex-end;
    gap: 9px;
    font-size: 11px;
}

.market-plate-grid .market-plate-metrics span {
    display: grid;
    gap: 2px;
    text-align: right;
}

.market-plate-grid .market-plate-metrics b {
    font-size: 12px;
}

.market-plate-body-summary {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 38px;
    padding: 0 0 8px;
}

.market-plate-body-label {
    flex: 0 0 auto;
    color: var(--text-muted);
    font-size: 11px;
}

.market-plate-body-summary .market-plate-stats {
    min-width: 0;
}

.market-plate-grid .market-plate-card-body {
    padding: 10px 14px 12px;
    background: var(--market-panel-muted);
}

.market-plate-grid .market-plate-stock-head,
.market-plate-grid .market-plate-stock {
    grid-template-columns: minmax(110px, 1.35fr) 42px 72px 60px 50px 72px minmax(80px, 0.9fr) minmax(90px, 1.1fr);
    gap: 7px;
}

.market-plate-grid .market-plate-stock-head {
    padding: 5px 7px;
    border-bottom: 1px solid var(--market-line);
}

.market-plate-grid .market-plate-stock {
    padding: 8px 7px;
    background: var(--market-panel);
}

.market-plate-grid .market-plate-stock + .market-plate-stock {
    border-top: 1px solid var(--market-line);
}

.market-plate-grid .market-plate-stock-name {
    gap: 5px;
}

.market-plate-grid .market-plate-stock-name strong {
    font-size: 12px;
}

.market-plate-grid .market-plate-stock-name small {
    font-size: 10px;
}

.market-plate-grid .market-plate-stock-step {
    font-size: 12px;
}

.market-plate-grid .market-plate-card.is-expanded {
    /* 展开后要展示 8 列个股明细，半栏宽度会把“涨停原因”挤掉，故跨满整行。 */
    grid-column: 1 / -1;
    box-shadow: none;
}

/* ==== Ladder view switch (theme / stock) ==== */

/* 总览头部右侧：统计 + 视角切换按钮 垂直排 */
.market-ladder-intro-side {
    display: grid;
    justify-items: end;
    align-content: end;
    gap: 6px;
}

.market-ladder-intro-side .market-ladder-intro-meta {
    padding-bottom: 0;
}

.market-ladder-view-switch {
    margin: 0;
}

/* 数据口径徽章：实时池与收盘数据必须一眼可辨，否则无法判断家数是盘中还是最终值。 */
.market-ladder-basis {
    padding: 2px 8px;
    border: 1px solid var(--market-line);
    border-radius: 999px;
    background: var(--market-panel-muted);
    color: var(--text-secondary);
    font-size: 11px;
    white-space: nowrap;
}

.market-ladder-basis.is-live {
    border-color: rgba(21, 118, 232, .45);
    background: rgba(21, 118, 232, .08);
    color: #1576e8;
    font-weight: 700;
}

/* ---- 个股视角：档位徽章 + 个股标签流 ---- */

.market-ladder-levels {
    display: grid;
    gap: 8px;
}

.market-ladder-level {
    display: grid;
    grid-template-columns: 92px minmax(0, 1fr);
    gap: 14px;
    padding: 10px 14px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.market-ladder-level-badge {
    display: grid;
    align-content: start;
    gap: 3px;
    padding: 4px 0 0 2px;
    border-right: 1px solid var(--market-line);
}

.market-ladder-level-badge strong {
    color: var(--market-up);
    font-size: 15px;
    font-variant-numeric: tabular-nums;
}

.market-ladder-level-badge.is-high strong {
    color: #dc2626;
}

.market-ladder-level-badge small {
    color: var(--text-muted);
    font-size: 11px;
    white-space: nowrap;
}

.market-ladder-level-stocks {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-width: 0;
}

.market-ladder-chip {
    display: inline-flex;
    align-items: baseline;
    gap: 6px;
    padding: 5px 9px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel-muted);
    color: var(--text-primary);
    font: inherit;
    font-size: 12px;
    line-height: 1.2;
    cursor: pointer;
    white-space: nowrap;
}

.market-ladder-chip:hover {
    border-color: #1576e8;
    background: var(--market-panel);
}

.market-ladder-chip span {
    color: var(--market-up);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.market-ladder-chip.is-high {
    border-color: rgba(220, 38, 38, .35);
}

.market-ladder-chip.is-promoted span::after {
    content: '晋';
    margin-left: 4px;
    padding: 0 3px;
    border-radius: 3px;
    background: var(--market-up-soft);
    color: var(--market-up);
    font-size: 10px;
}

/* ==== Plate rotation heatmap ==== */

.market-rotation-cell.is-heat {
    padding: 3px;
}

.market-heat-cell {
    display: grid;
    place-items: center;
    gap: 1px;
    min-height: 44px;
    padding: 4px 6px;
    border-radius: 6px;
    background: rgba(220, 38, 38, calc(0.04 + var(--heat, 0) * 0.0055));
    color: var(--text-primary);
}

.market-heat-cell b {
    font-size: 13px;
}

.market-heat-cell small {
    color: var(--text-muted);
    font-size: 10px;
}

.market-heat-cell.is-latest-true {
    outline: 1.5px solid rgba(220, 38, 38, 0.45);
    outline-offset: -1.5px;
}

/* ==== Plate drawer ==== */

.market-plate-drawer {
    position: fixed;
    inset: 0;
    z-index: 90;
    display: flex;
    align-items: flex-end;
    justify-content: flex-end;
    padding: 16px;
}

.market-plate-drawer.hidden {
    display: none;
}

.market-plate-drawer-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, 0.42);
    cursor: pointer;
}

.market-plate-drawer-panel {
    position: relative;
    z-index: 1;
    display: flex;
    flex-direction: column;
    width: min(680px, calc(100vw - 32px));
    height: min(560px, calc(100vh - 32px));
    max-height: calc(100vh - 32px);
    min-height: 0;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    box-shadow: 0 18px 48px rgba(15, 23, 42, 0.2);
    overflow: hidden;
}

.market-plate-drawer-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    padding: 16px 20px;
    border-bottom: 1px solid var(--market-line);
}

.market-plate-drawer-head h3 {
    margin: 2px 0 0;
    font-size: 20px;
}

.market-plate-drawer-body {
    padding: 16px 20px 28px;
    overflow-y: auto;
    font-size: 13px;
}

.market-plate-drawer-body h4 {
    margin: 16px 0 8px;
    font-size: 13px;
}

.market-drawer-stage {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
    padding: 10px 12px;
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.market-drawer-stage > span:first-child {
    color: var(--text-muted);
    font-size: 12px;
}

.market-drawer-bars {
    display: flex;
    align-items: flex-end;
    gap: 8px;
    min-height: 120px;
    padding: 8px 4px 0;
    overflow-x: auto;
}

.market-drawer-bar {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    gap: 3px;
    min-width: 44px;
    flex: 1 0 44px;
}

.market-drawer-bar i {
    display: block;
    width: 100%;
    max-width: 30px;
    border-radius: 4px 4px 0 0;
    background: #1576e8;
}

.market-drawer-bar small {
    color: var(--text-muted);
    font-size: 10px;
}

.market-drawer-bar b {
    font-size: 12px;
}

@media (max-width: 1180px) {
    #market-promotion-strip {
        grid-template-columns: repeat(4, minmax(0, 1fr));
    }

    #market-promotion-strip .market-metric-cell:nth-child(4n) {
        border-right: 0;
    }

    #market-promotion-strip .market-metric-cell:nth-child(n+5) {
        border-top: 1px solid var(--market-line);
    }

    .market-plate-grid {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 760px) {
    .market-plate-drawer {
        padding: 12px;
    }

    .market-plate-drawer-panel {
        width: 100%;
        height: min(560px, calc(100vh - 24px));
        max-height: calc(100vh - 24px);
    }

    #market-promotion-strip {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    #market-promotion-strip .market-metric-cell,
    #market-promotion-strip .market-metric-cell:nth-child(4n) {
        border-right: 1px solid var(--market-line);
    }

    #market-promotion-strip .market-metric-cell:nth-child(2n) {
        border-right: 0;
    }

    #market-promotion-strip .market-metric-cell:nth-child(n+3) {
        border-top: 1px solid var(--market-line);
    }

    .market-ladder-intro {
        align-items: flex-start;
        flex-direction: column;
        gap: 4px;
    }

    .market-ladder-intro-side {
        justify-items: start;
        align-content: start;
        width: 100%;
    }

    .market-ladder-level {
        grid-template-columns: 1fr;
        gap: 8px;
        padding: 10px 12px;
    }

    .market-ladder-level-badge {
        grid-auto-flow: column;
        justify-content: start;
        align-items: baseline;
        gap: 8px;
        padding: 0;
        border-right: 0;
        border-bottom: 1px dashed var(--market-line);
        padding-bottom: 6px;
    }

    .market-plate-grid .market-plate-card-head {
        grid-template-columns: 24px minmax(0, 1fr) 62px 22px;
        gap: 8px;
        min-height: 76px;
        padding: 11px 12px;
    }

    .market-plate-lead {
        display: none;
    }

    .market-plate-height {
        padding-left: 7px;
    }

    .market-plate-height strong {
        font-size: 20px;
    }

    .market-plate-grid .market-plate-metrics {
        display: contents;
    }

    .market-plate-grid .market-plate-metrics span {
        display: none;
    }

    .market-plate-grid .market-plate-metrics .market-plate-caret {
        display: block;
        grid-column: 4;
        grid-row: 1;
    }

    .market-plate-grid .market-plate-stock-head,
    .market-plate-grid .market-plate-stock {
        grid-template-columns: minmax(100px, 1.4fr) 40px 68px minmax(80px, 1fr);
    }

    /* 窄屏只保留：个股 / 连板 / 涨跌幅 / 涨停原因 */
    .market-plate-grid .market-plate-stock-head span:nth-child(4),
    .market-plate-grid .market-plate-stock-head span:nth-child(5),
    .market-plate-grid .market-plate-stock-head span:nth-child(6),
    .market-plate-grid .market-plate-stock-head span:nth-child(7),
    .market-plate-grid .market-plate-stock span:nth-child(4),
    .market-plate-grid .market-plate-stock span:nth-child(5),
    .market-plate-grid .market-plate-stock span:nth-child(6),
    .market-plate-grid .market-plate-stock span:nth-child(7) {
        display: none;
    }
}

/* ==== Theme rotation workspace ==== */

.market-rotation-summary {
    margin-top: 26px;
}

.market-rotation-callout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 190px;
    gap: 24px;
    padding: 20px 22px;
    border: 1px solid rgba(21, 118, 232, .24);
    border-left: 4px solid #1576e8;
    border-radius: 8px;
    background: #eaf2fd;
}

[data-theme="dark"] .market-rotation-callout {
    background: rgba(21, 118, 232, .1);
}

.market-rotation-callout-main {
    min-width: 0;
}

.market-rotation-eyebrow {
    display: block;
    color: #1576e8;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .04em;
}

.market-rotation-callout h3,
.market-rotation-surface-head h3,
.market-rotation-board-head h3 {
    margin: 4px 0 0;
    color: var(--text-primary);
    font-size: 18px;
    line-height: 1.3;
}

.market-rotation-callout p {
    max-width: 780px;
    margin: 9px 0 0;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.6;
}

.market-rotation-callout-tags {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 14px;
}

.market-rotation-callout-tags span {
    padding: 4px 8px;
    border: 1px solid var(--market-line);
    border-radius: 999px;
    background: var(--market-panel);
    color: var(--text-secondary);
    font-size: 11px;
}

.market-rotation-callout-tags span.is-risk {
    border-color: rgba(180, 83, 9, .3);
    background: var(--market-amber-soft);
    color: var(--market-amber);
}

.market-rotation-window {
    display: grid;
    align-content: center;
    gap: 9px;
    padding-left: 22px;
    border-left: 1px solid rgba(21, 118, 232, .18);
}

.market-rotation-window-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
}

.market-rotation-window span,
.market-rotation-window small {
    color: var(--text-muted);
    font-size: 11px;
}

.market-rotation-window-head > span {
    color: var(--text-secondary);
    font-weight: 700;
}

.market-rotation-window-options {
    display: grid;
    grid-auto-flow: column;
    grid-auto-columns: minmax(0, 1fr);
    overflow: hidden;
    border: 1px solid rgba(21, 118, 232, .25);
    border-radius: 6px;
    background: var(--market-panel);
}

.market-rotation-window-options button {
    min-width: 0;
    height: 30px;
    padding: 0 5px;
    border: 0;
    border-right: 1px solid var(--market-line);
    background: transparent;
    color: var(--text-secondary);
    cursor: pointer;
    font: inherit;
    font-size: 11px;
}

.market-rotation-window-options button:last-child {
    border-right: 0;
}

.market-rotation-window-options button:hover,
.market-rotation-window-options button:focus-visible,
.market-rotation-window-options button.active {
    background: #1576e8;
    color: #fff;
}

.market-rotation-window-options button:focus-visible {
    outline: 2px solid #1576e8;
    outline-offset: -2px;
}

.market-rotation-window-range {
    min-height: 14px;
    line-height: 1.35;
    white-space: nowrap;
}

.market-rotation-overview-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 12px;
    margin-top: 12px;
}

.market-rotation-surface {
    min-width: 0;
    padding: 16px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.market-rotation-surface-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 14px;
}

.market-rotation-surface-head .market-muted {
    font-size: 11px;
    white-space: nowrap;
}

.market-rotation-timeline {
    display: grid;
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 28px;
    align-items: stretch;
}

.market-rotation-timeline-item {
    position: relative;
    display: flex;
    flex-direction: column;
    justify-content: center;
    gap: 6px;
    min-width: 0;
    min-height: 96px;
    padding: 12px 14px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
    box-shadow: none;
}

.market-rotation-timeline-item.is-current {
    border-color: rgba(21, 118, 232, .55);
    background: var(--market-down-soft);
    box-shadow: 0 0 0 1px rgba(21, 118, 232, .35);
}

.market-rotation-timeline-item > small {
    color: var(--text-muted);
    font-size: 11px;
    letter-spacing: .02em;
}

.market-rotation-timeline-item button {
    min-width: 0;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--text-primary);
    text-align: left;
    cursor: pointer;
    font: inherit;
}

.market-rotation-timeline-item button:hover strong,
.market-rotation-timeline-item button:focus-visible strong {
    color: #1576e8;
}

.market-rotation-timeline-item button:focus-visible,
.market-rotation-watch-item:focus-visible {
    outline: 2px solid #1576e8;
    outline-offset: 2px;
}

.market-rotation-timeline-item strong,
.market-rotation-timeline-item small {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-rotation-timeline-item strong {
    font-size: 15px;
    letter-spacing: -.01em;
}

.market-rotation-timeline-item button small {
    margin-top: 3px;
    color: var(--text-muted);
    font-size: 11px;
}

.market-rotation-timeline-item > i {
    position: absolute;
    top: 50%;
    right: -20px;
    z-index: 1;
    color: #94a3b8;
    font-size: 14px;
    font-style: normal;
    line-height: 1;
    transform: translateY(-50%);
}

.market-rotation-timeline-empty {
    color: var(--text-muted);
    font-size: 11px;
}

.market-rotation-watch-groups {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 12px;
}

.market-rotation-watch-group {
    min-width: 0;
    padding: 12px 14px 6px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.market-rotation-watch-group:first-child {
    padding-top: 12px;
    border-top: 1px solid var(--market-line);
}

.market-rotation-watch-head {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 6px;
}

.market-rotation-watch-head em {
    flex: 0 0 auto;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--text-muted);
}

.market-rotation-watch-head span {
    color: var(--text-muted);
    font-size: 10px;
}

.market-rotation-watch-head strong {
    color: var(--text-secondary);
    font-size: 12px;
}

.market-rotation-watch-group.is-main .market-rotation-watch-head strong {
    color: #1576e8;
}

.market-rotation-watch-group.is-main .market-rotation-watch-head em {
    background: #1576e8;
}

.market-rotation-watch-group.is-rising .market-rotation-watch-head strong {
    color: var(--market-amber);
}

.market-rotation-watch-group.is-rising .market-rotation-watch-head em {
    background: var(--market-amber);
}

.market-rotation-watch-group.is-risk .market-rotation-watch-head strong {
    color: var(--market-up);
}

.market-rotation-watch-group.is-risk .market-rotation-watch-head em {
    background: var(--market-up);
}

.market-rotation-watch-item {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 64px 36px;
    align-items: center;
    gap: 8px;
    width: 100%;
    min-height: 42px;
    padding: 5px 0;
    border: 0;
    border-bottom: 1px solid var(--market-line);
    background: transparent;
    color: var(--text-primary);
    text-align: left;
    cursor: pointer;
    font: inherit;
}

.market-rotation-watch-item:last-child {
    border-bottom: 0;
}

.market-rotation-watch-item > span:first-child,
.market-rotation-watch-value {
    min-width: 0;
}

.market-rotation-watch-item strong,
.market-rotation-watch-item small {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-rotation-watch-item strong {
    font-size: 12px;
}

.market-rotation-watch-item small {
    margin-top: 2px;
    color: var(--text-muted);
    font-size: 10px;
}

.market-rotation-watch-value {
    text-align: right;
}

.market-rotation-watch-value b {
    display: block;
    font-size: 14px;
    font-variant-numeric: tabular-nums;
}

.market-rotation-watch-item em {
    color: var(--text-muted);
    font-size: 11px;
    font-style: normal;
    text-align: right;
}

.market-rotation-watch-group.is-rising .market-rotation-watch-item em {
    color: var(--market-amber);
}

.market-rotation-watch-group.is-risk .market-rotation-watch-item em {
    color: var(--market-up);
}

.market-rotation-watch-empty {
    padding: 8px 0;
    color: var(--text-muted);
    font-size: 11px;
}

.market-rotation-board {
    margin-top: 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    overflow: hidden;
}

.market-rotation-board-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 16px;
    padding: 16px 16px 12px;
}

.market-rotation-board-head p {
    margin: 5px 0 0;
    color: var(--text-muted);
    font-size: 11px;
}

.market-rotation-legend {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    color: var(--text-muted);
    font-size: 11px;
    white-space: nowrap;
}

.market-rotation-legend span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}

.market-rotation-legend i {
    width: 12px;
    height: 12px;
    border: 1px solid transparent;
    border-radius: 3px;
}

.market-rotation-legend i.is-low,
.market-heat-cell.is-low {
    background: #f5f6f8;
    border-color: #e8eaee;
}

.market-rotation-legend i.is-active,
.market-heat-cell.is-active {
    background: #dbe9fb;
    border-color: #a9cdf5;
}

.market-rotation-legend i.is-hot,
.market-heat-cell.is-hot {
    background: #ffe4c2;
    border-color: #f2bd78;
}

.market-rotation-filters {
    display: flex;
    gap: 6px;
    padding: 0 16px 12px;
}

.market-rotation-filters button {
    min-height: 28px;
    padding: 4px 10px;
    border: 1px solid var(--market-line);
    border-radius: 5px;
    background: var(--market-panel);
    color: var(--text-secondary);
    font: inherit;
    font-size: 11px;
    cursor: pointer;
}

.market-rotation-filters button:hover,
.market-rotation-filters button.active {
    border-color: #1576e8;
    background: var(--market-down-soft);
    color: #1576e8;
}

.market-rotation-board .market-rotation-wrap {
    border: 0;
    border-top: 1px solid var(--market-line);
    border-radius: 0;
}

.market-rotation-table {
    min-width: 940px;
    table-layout: fixed;
}

.market-rotation-table th,
.market-rotation-table td {
    height: 64px;
    padding: 6px;
    text-align: center;
    vertical-align: middle;
}

.market-rotation-table th:first-child,
.market-rotation-table td:first-child {
    width: 196px;
    text-align: left;
}

.market-rotation-table th:first-child,
.market-rotation-table th.is-current {
    background: #eaf2fd;
    color: #1576e8;
}

[data-theme="dark"] .market-rotation-table th:first-child,
[data-theme="dark"] .market-rotation-table th.is-current {
    background: rgba(21, 118, 232, .12);
}

.market-rotation-table th.is-current small {
    display: block;
    margin-top: 3px;
    color: #1576e8;
    font-size: 10px;
    font-weight: 700;
}

.market-rotation-table td:first-child {
    position: sticky;
    left: 0;
    z-index: 1;
    background: var(--market-panel);
}

.market-rotation-table tr:hover td:first-child {
    background: var(--market-panel-muted);
}

.market-rotation-theme-button {
    display: block;
    width: 100%;
    padding: 4px 6px;
    border: 0;
    border-left: 3px solid transparent;
    background: transparent;
    color: inherit;
    text-align: left;
    cursor: pointer;
    font: inherit;
}

.market-rotation-theme-button:hover {
    border-left-color: #1576e8;
}

.market-rotation-theme-button strong,
.market-rotation-theme-button small {
    display: block;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-rotation-theme-button strong {
    font-size: 12px;
}

.market-rotation-theme-button small {
    margin-top: 4px;
    color: var(--text-muted);
    font-size: 10px;
}

.market-rotation-cell {
    padding: 4px !important;
    background: var(--market-panel);
}

.market-rotation-cell.is-missing {
    color: var(--text-muted);
    background: var(--market-panel-muted);
}

.market-heat-cell {
    position: relative;
    display: grid;
    grid-template-columns: 1fr auto;
    grid-template-rows: auto auto;
    width: 100%;
    align-items: center;
    min-height: 52px;
    padding: 5px 7px;
    border: 1px solid transparent;
    border-radius: 5px;
    color: inherit;
    background: transparent;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.market-heat-cell:hover {
    border-color: #1576e8;
    filter: brightness(.98);
}

.market-heat-cell:focus-visible {
    outline: 2px solid var(--primary);
    outline-offset: 1px;
}

[data-theme="dark"] .market-rotation-legend i.is-low,
[data-theme="dark"] .market-heat-cell.is-low {
    background: rgba(148, 163, 184, .11);
    border-color: rgba(148, 163, 184, .18);
}

[data-theme="dark"] .market-rotation-legend i.is-active,
[data-theme="dark"] .market-heat-cell.is-active {
    background: rgba(21, 118, 232, .18);
    border-color: rgba(21, 118, 232, .3);
}

[data-theme="dark"] .market-rotation-legend i.is-hot,
[data-theme="dark"] .market-heat-cell.is-hot {
    background: rgba(245, 158, 11, .2);
    border-color: rgba(245, 158, 11, .34);
}

.market-heat-cell.is-latest {
    box-shadow: inset 0 0 0 2px #1576e8;
}

.market-heat-cell b {
    color: var(--text-primary);
    font-size: 15px;
    line-height: 1;
}

.market-heat-cell small,
.market-heat-cell em {
    color: var(--text-muted);
    font-size: 10px;
    font-style: normal;
    line-height: 1.2;
}

.market-heat-cell small {
    grid-column: 1;
    grid-row: 2;
    margin-top: 3px;
}

.market-heat-cell em {
    grid-column: 2;
    grid-row: 2;
    align-self: end;
    margin-top: 3px;
}

.market-heat-cell i {
    position: absolute;
    top: 4px;
    right: 5px;
    color: #1576e8;
    font-size: 10px;
    font-style: normal;
    line-height: 1;
}

@media (max-width: 1000px) {
    .market-rotation-watch-groups {
        grid-template-columns: 1fr;
    }
}

@media (max-width: 760px) {
    .market-rotation-callout {
        grid-template-columns: 1fr;
        gap: 14px;
        padding: 16px;
    }

    .market-rotation-window {
        gap: 8px;
        padding: 12px 0 0;
        border-top: 1px solid rgba(21, 118, 232, .18);
        border-left: 0;
    }

    .market-rotation-window-options {
        max-width: 320px;
    }

    .market-rotation-timeline {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 10px;
    }

    .market-rotation-timeline-item > i {
        display: none;
    }

    .market-rotation-board-head {
        align-items: flex-start;
        flex-direction: column;
        gap: 10px;
    }

    .market-rotation-filters {
        overflow-x: auto;
        padding-bottom: 10px;
    }

    .market-rotation-filters button {
        flex: 0 0 auto;
    }
}

/* ==== Market sentiment lab redesign ==== */
.market-page-head {
    align-items: flex-start;
    padding: 6px 0 22px;
}
.market-page-head h2 { font-size: 34px; letter-spacing: -.04em; }
.market-page-subtitle {
    max-width: 560px;
    margin: 8px 0 0;
    color: var(--text-secondary);
    font-size: 13px;
    line-height: 1.55;
}
/* 阶段条替代原来的综合温度 hero：分数被删，阶段和一句结构判断留下。 */
.market-stage-strip {
    padding: 20px 0 22px;
    border-bottom: 1px solid var(--market-line);
}
.market-stage-strip .market-cycle-banner { margin-top: 0; }
.market-stage-foot {
    display: flex;
    justify-content: space-between;
    gap: 12px;
    margin: 14px 0 0;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.5;
}
.market-stage-foot span:last-child { color: var(--text-muted); white-space: nowrap; }
.market-section-desc { margin: 5px 0 0; color: var(--text-muted); font-size: 12px; line-height: 1.5; }
.market-dimension-section { padding-top: 27px; }
.market-context-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 13px; }
.market-context-axis { padding: 17px 17px 15px; border-radius: 8px; box-shadow: none; }
.market-context-axis-head { align-items: flex-start; }
.market-context-axis-head > span { color: var(--text-primary); font-size: 14px; font-weight: 800; }
.market-context-axis strong { margin: 14px 0 10px; font-size: 34px; letter-spacing: -.05em; }
.market-context-axis-formula { min-height: 34px; margin: 11px 0 7px; font-size: 11px; }
.market-context-axis-facts { min-height: 42px; align-content: flex-start; color: var(--text-secondary); }
.market-context-axis-risk { background: linear-gradient(145deg, var(--market-panel), rgba(254, 242, 242, .72)); }
.market-context-axis-risk .market-context-track i { background: #dc2626; }
/* 四维本来是六项的上卷，不再单独占一屏：压成一行汇总条，只回答「哪一维在推动、
   哪一维在拖累」，明细交给下方的六项因子。字号与留白各收一档，避免两张同源面板
   上下各占一屏。 */
.market-context-grid.market-dimension-inline { gap: 10px; }
.market-context-grid.market-dimension-inline .market-context-axis { padding: 10px 12px; border-radius: 8px; box-shadow: none; }
.market-context-grid.market-dimension-inline .market-context-axis strong { margin: 6px 0 4px; font-size: 22px; }
.market-context-grid.market-dimension-inline .market-context-axis-formula { min-height: 0; margin: 4px 0 3px; }
.market-context-grid.market-dimension-inline .market-context-axis-facts { min-height: 0; }
.market-component-section { padding-top: 27px; }
.market-component-bars { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 7px 28px; padding: 13px 16px; border: 1px solid var(--market-line); border-radius: 8px; background: var(--market-panel-muted); }
.market-component-bars .market-component-row { margin: 0; padding: 8px 7px; grid-template-columns: minmax(75px, 110px) minmax(60px, 1fr) 36px 40px 40px; }
.market-component-bars .market-component-row:nth-child(-n+2) { border-bottom: 1px solid var(--market-line); }
.market-trend-section { padding-top: 27px; }
@media (max-width: 900px) {
    .market-context-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 640px) {
    .market-page-head { display: grid; gap: 15px; }
    .market-page-head h2 { font-size: 29px; }
    .market-stage-foot { display: grid; gap: 4px; }
}



/* ---- 历史轮动复盘（rotation replay, History Replay board）---- */
#market-replay-board .market-replay-summary { display: block; border: 0; background: transparent; padding: 0; }
.market-replay-current { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 10px; }
.market-replay-current-cell { display: grid; gap: 3px; padding: 10px 12px; border: 1px solid var(--market-line); border-radius: 8px; background: var(--market-panel); }
.market-replay-current-cell span { font-size: 11px; color: var(--text-secondary); }
.market-replay-current-cell strong { font-size: 15px; color: var(--text-primary); }
.market-replay-current-cell small { font-size: 11px; color: var(--text-secondary); }
.market-replay-matches { display: grid; gap: 12px; margin-top: 12px; }
.market-replay-match { border: 1px solid var(--market-line); border-radius: 8px; padding: 12px 14px; background: var(--market-panel); display: grid; gap: 8px; }
.market-replay-match header { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.market-replay-match header b { color: #1576e8; font-size: 13px; }
.market-replay-match header strong { font-size: 14px; }
.market-replay-match header em { font-style: normal; font-weight: 600; color: #1576e8; }
.market-replay-match header small { color: var(--text-secondary); }
.market-replay-regime { font-size: 11px; padding: 2px 8px; border-radius: 999px; border: 1px solid var(--market-line); color: var(--text-secondary); }
.market-replay-centers { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; font-size: 12px; }
.market-replay-centers i { color: var(--text-secondary); font-style: normal; }
.market-replay-center { padding: 2px 8px; border-radius: 6px; background: rgba(21, 118, 232, 0.08); }
.market-replay-center.is-switch { outline: 1px dashed rgba(21, 118, 232, 0.5); }
.market-replay-stats { display: flex; flex-wrap: wrap; gap: 12px; font-size: 12px; color: var(--text-secondary); }
.market-replay-posts { border-top: 1px dashed var(--market-line); padding-top: 8px; display: grid; gap: 4px; }
.market-replay-post-title { font-size: 12px; font-weight: 600; color: var(--text-primary); }
.market-replay-post-row { display: flex; gap: 8px; align-items: baseline; font-size: 12px; }
.market-replay-post-row > span { min-width: 34px; font-weight: 600; color: #1576e8; }
.market-replay-post-row small { color: var(--text-secondary); }
.market-theme-strength-row { cursor: pointer; }
.market-rotation-table tr.is-highlight > td { background: rgba(21, 118, 232, 0.10) !important; }
.market-rotation-table tr.is-highlight > td:first-child { box-shadow: inset 3px 0 0 #1576e8; }
@media (max-width: 1100px) {
    .market-replay-current { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

/* ---- 题材主线布局修正（两张独立榜单共用限高滚动与固定表头）---- */
.market-rotation-overview-grid { align-items: start; }
#market-emotion-board .market-table-wrap,
#market-theme-strength-board .market-table-wrap {
    max-height: 520px;
    overflow-y: auto;
}
#market-emotion-board .market-table thead th,
#market-theme-strength-board .market-table thead th {
    position: sticky;
    top: 0;
    z-index: 2;
    background: var(--market-panel-muted);
}
.market-emotion-row { cursor: pointer; }
.market-emotion-row.is-highlight > td,
.market-theme-strength-row.is-highlight > td {
    background: rgba(21, 118, 232, 0.10) !important;
}
.market-emotion-row.is-highlight > td:first-child,
.market-theme-strength-row.is-highlight > td:first-child {
    box-shadow: inset 3px 0 0 #1576e8;
}

/* ---- 首屏市场状态地图 ---- */
.market-state-map {
    padding: 13px 0 14px;
    border-bottom: 1px solid var(--market-line);
}
.market-state-map-head,
.market-state-surface-head,
.market-state-layer-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 14px;
}
.market-state-map-head {
    margin-bottom: 10px;
}
.market-state-map-head h3,
.market-state-map-head h4 {
    margin: 2px 0 0;
    font-size: 18px;
    line-height: 1.25;
    letter-spacing: 0;
}
.market-state-map-head p {
    margin: 5px 0 0;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.5;
}
.market-state-coverage {
    flex: none;
    padding: 5px 9px;
    border: 1px solid var(--market-line);
    border-radius: 5px;
    background: var(--market-panel-muted);
    color: var(--text-secondary);
    font: inherit;
    font-size: 11px;
    white-space: nowrap;
    cursor: pointer;
}
.market-state-coverage:hover {
    border-color: var(--market-ink);
    color: var(--text-primary);
}
.market-state-coverage::after { content: ' ▾'; color: var(--text-muted); }
.market-state-coverage[aria-expanded="true"]::after { content: ' ▴'; }
.market-state-map[data-status="partial"] .market-state-coverage {
    border-color: rgba(180, 83, 9, .35);
    background: var(--market-amber-soft);
    color: var(--market-amber);
}
.market-state-map[data-status="unavailable"] .market-state-coverage,
.market-state-map[data-status="unknown"] .market-state-coverage {
    border-color: rgba(4, 120, 87, .35);
    background: var(--market-down-soft);
    color: var(--market-down);
}
/* 数据可信度展开层：回答「哪部分不可用、各占多少权重、分数被压缩在多宽的区间里」。
   这三件事后端都已给出（coverage.missing / degraded_reasons / score_lower·upper），
   此前前端只渲染「部分可用 · 状态指标 70%」，用户无法判断该不该信这个点位。 */
.market-state-coverage-detail {
    margin: -6px 0 14px;
    padding: 13px 15px;
    border: 1px solid var(--market-line);
    background: var(--market-panel-muted);
}
.market-state-coverage-detail h4 {
    margin: 0 0 8px;
    color: var(--text-primary);
    font-size: 12px;
}
.market-state-coverage-detail h4 + h4 { margin-top: 13px; }
.market-state-coverage-detail p {
    margin: 0;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.6;
}
.market-state-coverage-list {
    display: grid;
    gap: 6px;
    margin: 0;
    padding: 0;
    list-style: none;
}
.market-state-coverage-list li {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    padding: 6px 9px;
    border: 1px solid var(--market-line);
    background: var(--market-panel);
    font-size: 12px;
}
.market-state-coverage-list b { color: var(--text-primary); font-weight: 700; }
.market-state-coverage-list span { color: var(--text-secondary); }
.market-state-coverage-list em {
    color: var(--market-amber);
    font-size: 11px;
    font-style: normal;
    white-space: nowrap;
}
.market-state-coverage-list li.is-hard em { color: var(--market-down); }
.market-state-map-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 14px;
}
.market-state-map-main,
.market-state-surface {
    border: 1px solid var(--market-line);
    background: var(--market-panel);
}
.market-state-map-main {
    min-width: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: 14px;
    padding: 11px 13px;
}
.market-state-summary {
    display: flex;
    min-width: 0;
    flex-direction: column;
    justify-content: center;
    padding: 8px 14px 8px 4px;
    border-right: 1px solid var(--market-line);
}
.market-state-summary > span,
.market-state-eyebrow {
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
}
.market-state-summary strong {
    margin: 5px 0 3px;
    color: var(--text-primary);
    font-size: 22px;
    line-height: 1.2;
}
.market-state-summary p {
    margin: 0;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.55;
}
/* 读数升级：把「一个象限词」补成「分数 + 较昨 + 分位 + 区间」。
   缺值一律渲染 `--` 而不隐藏整行——行高跳动比一个 `--` 更难读。
   左侧摘要在 1280px 视口只有 ~151px 宽，一行放不下「标签 + 分数 + 较昨 + 分位」：
   三列版式里 auto 列会吃光全部宽度，把分数列压成 0px，分数直接叠在较昨文字上。
   所以改成两行——首行「标签 | 分数」，次行整宽放明细。 */
.market-state-readings {
    display: grid;
    gap: 5px;
    margin: 9px 0 0;
}
.market-state-reading {
    display: grid;
    grid-template-columns: minmax(48px, auto) minmax(0, 1fr);
    align-items: baseline;
    column-gap: 8px;
    row-gap: 1px;
    font-size: 12px;
}
.market-state-reading > span {
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
    white-space: nowrap;
}
.market-state-reading > b {
    color: var(--text-primary);
    font-size: 15px;
    font-weight: 800;
    justify-self: end;
}
.market-state-reading > small {
    grid-column: 1 / -1;
    color: var(--text-secondary);
    font-size: 11px;
}
/* 「近10日 100% 分位」是一个整体，不允许在「近10」与「日」之间断开。 */
.market-state-percentile { white-space: nowrap; }
.market-state-reading > small.is-up { color: var(--market-up); }
.market-state-reading > small.is-down { color: var(--market-down); }
/* 区间条：partial 下同一个分数对应的可信范围。不透明条 = 分数可能落在的范围，
   竖线 = 当前值。区间跨过 55 时，条本身就把「象限可能翻转」说清楚了。
   条嵌在读数行内部并横跨整行，避免它作为独立网格行时与读数脱开。 */
.market-state-reading-bar {
    position: relative;
    grid-column: 1 / -1;
    height: 3px;
    margin-top: -3px;
    background: var(--market-line);
}
.market-state-reading-bar i {
    position: absolute;
    top: 0;
    bottom: 0;
    left: var(--market-state-range-start, 0%);
    right: calc(100% - var(--market-state-range-end, 0%));
    background: var(--market-amber);
    opacity: .55;
}
.market-state-reading-bar u {
    position: absolute;
    top: -2px;
    width: 2px;
    height: 7px;
    background: var(--text-primary);
    text-decoration: none;
}
/* 数据区与轴标签分离：标签留在 plot 的 padding 里，数据点只能落在 canvas 内。
   此前标签与轨迹点同处一个定位上下文、同为 z-index 3，后插入的轨迹点直接压住文字。
   两个前提缺一不可：
   1) plot 必须是定位上下文——轴标签是 absolute + 百分比偏移，plot 若为 static，
      它们的包含块会一路逃到 main，整组轴文字落到图表之外几千像素处；
   2) plot 不能跟着右侧文字列一起被拉伸——默认 stretch 时 plot 高 595px 而 canvas 只有
      266px，bottom 定位的轴标签会掉进图表下方近 300px 的空白里。图是卡片，按内容定高。
   padding-bottom 26px 是横轴说明行（低 / 热闹度 / 高）的容身之处：标签高 16px，
   bottom: 8px 时底边距 padding 底 8px，正好落在 canvas 下沿之外 2px。
   左内边距与上内边距走变量：竖排标签的宽度用左带，标签 top 用上下带之差对到 canvas
   中线。这样任何断点下只改变量，标签带与数据区留白不会脱钩。 */
.market-state-plot {
    --market-state-y-band: 24px;
    --market-state-pad-top: 6px;
    --market-state-pad-bottom: 22px;
    position: relative;
    align-self: start;
    display: grid;
    min-width: 0;
    padding: var(--market-state-pad-top) 10px var(--market-state-pad-bottom) var(--market-state-y-band);
    border: 1px solid var(--market-line);
    background: var(--market-panel-muted);
    box-sizing: border-box;
}
.market-state-canvas {
    position: relative;
    min-width: 0;
    height: 286px;
    min-height: 280px;
    overflow: hidden;
}
.market-state-map-error {
    margin: -6px 0 12px;
    padding: 8px 10px;
    border: 1px solid rgba(180, 83, 9, .35);
    background: var(--market-amber-soft);
    color: var(--market-amber);
    font-size: 11.5px;
    line-height: 1.55;
}
.market-state-zone {
    position: absolute;
    display: flex;
    padding: 8px 10px;
    box-sizing: border-box;
    color: rgba(27, 30, 36, .58);
    font-size: 10px;
    font-weight: 650;
    opacity: .78;
}
.market-state-zone span { max-width: 100%; }
/* 四个象限按后端阈值切分：横轴分界 --market-state-split-x，纵轴分界 --market-state-split-y。
   此前底色与分界线写死 50% 而标注写 55，于是 52.9 这样的分数落在分界线右侧，
   却被后端判成「安静地赚钱」——图和词对不上。变量由 JS 用 state_map.threshold 写入，
   默认 55% 只是首屏渲染前的兜底。纵轴变量存的是分数，top 方向要取反（分数越高越靠上）。 */
.market-state-zone-cold {
    left: 0;
    bottom: 0;
    width: var(--market-state-split-x, 55%);
    height: var(--market-state-split-y, 55%);
    align-items: flex-end;
    background: rgba(4, 120, 87, .08);
}
.market-state-zone-quiet {
    left: 0;
    top: 0;
    width: var(--market-state-split-x, 55%);
    height: calc(100% - var(--market-state-split-y, 55%));
    align-items: flex-start;
    background: rgba(18, 163, 102, .11);
}
.market-state-zone-hot {
    right: 0;
    top: 0;
    width: calc(100% - var(--market-state-split-x, 55%));
    height: calc(100% - var(--market-state-split-y, 55%));
    background: rgba(220, 38, 38, .10);
}
.market-state-zone-false {
    right: 0;
    bottom: 0;
    width: calc(100% - var(--market-state-split-x, 55%));
    height: var(--market-state-split-y, 55%);
    background: rgba(180, 83, 9, .10);
}
/* 当前样本没有覆盖后端阈值时，分界线不在可见范围内。此时任何象限底色
   都会把自适应坐标误读成绝对分界，所以横轴或纵轴任一阈值不可见时，
   四个象限一起隐藏；样本覆盖阈值后自动恢复。 */
.market-state-canvas:not(.has-split-x) .market-state-zone,
.market-state-canvas:not(.has-split-y) .market-state-zone {
    display: none;
}
.market-state-canvas:not(.has-split-x) .market-state-axis-line-y,
.market-state-canvas:not(.has-split-x) .market-state-threshold-x,
.market-state-canvas:not(.has-split-y) .market-state-axis-line-x,
.market-state-canvas:not(.has-split-y) .market-state-threshold-y {
    display: none;
}
.market-state-axis-line {
    position: absolute;
    z-index: 2;
    pointer-events: none;
    background: rgba(27, 30, 36, .2);
}
.market-state-axis-line-x { left: 0; right: 0; top: calc(100% - var(--market-state-split-y, 55%)); height: 1px; }
.market-state-axis-line-y { top: 0; bottom: 0; left: var(--market-state-split-x, 55%); width: 1px; }
.market-state-trail-line {
    position: absolute;
    z-index: 3;
    inset: 0;
    width: 100%;
    height: 100%;
    overflow: visible;
    pointer-events: none;
}
.market-state-trail-line polyline {
    fill: none;
    stroke: rgba(21, 118, 232, .72);
    stroke-width: 1.6;
    stroke-linecap: round;
    stroke-linejoin: round;
    vector-effect: non-scaling-stroke;
}
.market-state-trail-line marker path {
    fill: rgba(21, 118, 232, .82);
}
.market-state-trail-dot {
    position: absolute;
    z-index: 3;
    left: var(--market-state-x, 50%);
    top: calc(100% - var(--market-state-y, 50%));
    width: 6px;
    height: 6px;
    border: 1px solid rgba(100, 116, 139, .38);
    border-radius: 50%;
    background: rgba(100, 116, 139, .34);
    box-shadow: none;
    transform: translate(-50%, -50%);
}
.market-state-trail-dot.is-context {
    opacity: .58;
}
.market-state-trail-dot.is-recent {
    z-index: 4;
    display: grid;
    width: 17px;
    height: 17px;
    place-items: center;
    border: 2px solid var(--market-panel);
    background: #1576e8;
    box-shadow: 0 0 0 1px rgba(21, 118, 232, .42);
    color: #fff;
    font-size: 8.5px;
    font-style: normal;
    font-weight: 800;
    line-height: 1;
}
.market-state-trail-dot.is-recent::after {
    content: attr(data-step);
}
.market-state-trail-dot.is-recent.is-last {
    box-shadow:
        0 0 0 1px rgba(21, 118, 232, .52),
        0 0 0 5px rgba(21, 118, 232, .10);
}
.market-state-trail-dot:focus-visible {
    outline: 2px solid var(--market-brand);
    outline-offset: 3px;
}
.market-state-trail-footer {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-top: 6px;
}
.market-state-trail-note {
    flex: 1 1 auto;
    margin: 0;
    color: var(--text-muted);
    font-size: 10.5px;
    line-height: 1.5;
    font-variant-numeric: tabular-nums;
}
.market-state-trail-legend {
    display: flex;
    flex: none;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 4px 10px;
    color: var(--text-muted);
    font-size: 9.5px;
    line-height: 1.5;
}
.market-state-trail-legend span {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    white-space: nowrap;
}
.market-state-trail-legend i {
    display: inline-block;
    flex: none;
    box-sizing: border-box;
}
.market-state-trail-legend i.is-context {
    width: 6px;
    height: 6px;
    border: 1px solid rgba(100, 116, 139, .38);
    border-radius: 50%;
    background: rgba(100, 116, 139, .34);
}
.market-state-trail-legend i.is-recent {
    width: 15px;
    height: 2px;
    background: #1576e8;
}
.market-state-trail-legend i.is-today {
    width: 12px;
    height: 12px;
    border: 2px solid var(--market-panel);
    border-radius: 50%;
    background: transparent;
    box-shadow: 0 0 0 2px #1576e8;
}
.market-state-marker {
    position: absolute;
    z-index: 6;
    left: var(--market-state-x, 50%);
    top: calc(100% - var(--market-state-y, 50%));
    width: 28px;
    height: 28px;
    border: 2px solid var(--market-panel);
    border-radius: 50%;
    background: transparent;
    box-shadow:
        0 0 0 2px #1576e8,
        0 0 0 7px rgba(21, 118, 232, .13);
    transform: translate(-50%, -50%);
}
/* 所选交易日用空心定位环包住轨迹末端，避免与近 5 日第 5 个编号点重叠。
   分项缺失导致分数只是区间时，再把定位环改成虚线并保留区间带。 */
.market-state-marker.is-uncertain {
    border-style: dashed;
}
.market-state-marker-band {
    position: absolute;
    z-index: 5;
    pointer-events: none;
    background: var(--market-amber);
    opacity: .3;
}
.market-state-marker-band.is-x {
    top: calc(100% - var(--market-state-y, 50%));
    height: 3px;
    left: var(--market-state-band-x-start, 0%);
    right: calc(100% - var(--market-state-band-x-end, 0%));
    transform: translateY(-50%);
}
.market-state-marker-band.is-y {
    left: var(--market-state-x, 50%);
    width: 3px;
    top: calc(100% - var(--market-state-band-y-end, 0%));
    bottom: var(--market-state-band-y-start, 0%);
    transform: translateX(-50%);
}
/* 象限分界就是后端阈值（当前 55），数字由 JS 用 state_map.threshold 写入。
   两个标注此前都停在 left: 50% 的同一列、内容又都是光秃秃的「55」，
   看上去像同一个数字被画了两遍，也说不清哪个属于哪条轴。
   现在各自贴到本轴上：横轴分界（热闹度）落在竖直分界线底端，纵轴分界（赚钱效率）
   落在水平分界线右端，并且都带上轴名。 */
.market-state-threshold {
    position: absolute;
    z-index: 3;
    color: rgba(100, 116, 139, .76);
    font-size: 9px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
    pointer-events: none;
}
/* 热闹度分界：贴在竖直分界线的下端，读作横轴上的一个刻度。 */
.market-state-threshold-x {
    left: var(--market-state-split-x, 55%);
    bottom: 2px;
    padding: 0 2px;
    background: var(--market-panel-muted);
    transform: translateX(-50%);
}
/* 赚钱效率分界：贴在水平分界线的右端，读作纵轴上的一个刻度。
   右端中点是四个象限文字之间的空档，不会压到任何象限标签。 */
.market-state-threshold-y {
    right: 0;
    top: calc(100% - var(--market-state-split-y, 55%));
    padding: 0 2px;
    background: var(--market-panel-muted);
    transform: translateY(-50%);
}
.market-state-x-label,
.market-state-y-label,
.market-state-scale {
    position: absolute;
    color: rgba(100, 116, 139, .8);
    font-size: 9.5px;
}
.market-state-x-label { left: 50%; bottom: 8px; transform: translateX(-50%); }
/* 竖排轴标签：rotate 是绕元素自身中心转的，所以旋转后的横向落点由「文字自身宽度」决定——
   4 个汉字 40px 宽时中心落在 x=26px，正好压到 x=27px 起的 canvas 上。
   固定 width 让旋转中心与文字长度脱钩：中心落在左内边距带正中，文字溢出部分
   （nowrap）在旋转后变成上下对称溢出，不再横穿数据区。
   top 减掉上下内边距之差的一半，把标签对到 canvas 的垂直中线，
   而不是含底部说明行的整个 plot 中线。 */
.market-state-y-label {
    left: 0;
    top: calc(50% + (var(--market-state-pad-top, 8px) - var(--market-state-pad-bottom, 26px)) / 2);
    width: var(--market-state-y-band, 26px);
    text-align: center;
    white-space: nowrap;
    transform: translateY(-50%) rotate(-90deg);
}
.market-state-scale-x-low { right: calc(100% - 10px); bottom: 6px; }
.market-state-scale-x-high { right: 10px; bottom: 6px; }
.market-state-scale-y-low { left: 5px; bottom: 30px; }
.market-state-scale-y-high { left: 5px; top: 2px; }
.market-state-map-side {
    display: grid;
    min-width: 0;
    gap: 14px;
}
.market-state-evidence {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    padding-top: 2px;
}
.market-state-evidence-block {
    min-width: 0;
    padding: 9px 10px;
    border: 1px solid var(--market-line);
    background: var(--market-panel-muted);
}
.market-state-evidence-block h5 {
    margin: 0 0 6px;
    color: var(--text-secondary);
    font-size: 11px;
    font-weight: 700;
}
.market-state-evidence-rows {
    display: grid;
    gap: 5px;
}
.market-state-evidence-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}
.market-state-evidence-row > span {
    display: flex;
    min-width: 0;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 5px;
}
.market-state-evidence-row b {
    color: var(--text-primary);
    font-size: 11.5px;
    font-weight: 650;
    white-space: normal;
    overflow-wrap: anywhere;
}
.market-state-evidence-row strong {
    color: var(--text-primary);
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.market-state-evidence-empty {
    margin: 0;
    color: var(--text-muted);
    font-size: 11px;
    line-height: 1.5;
}
.market-state-loss {
    min-width: 0;
    padding-top: 2px;
}
.market-state-loss-head {
    display: flex;
    align-items: flex-start;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 8px;
}
.market-state-loss-head h5 {
    margin: 0;
    color: var(--text-primary);
    font-size: 12px;
    font-weight: 750;
}
.market-state-loss-head p {
    margin: 2px 0 0;
    color: var(--text-muted);
    font-size: 10.5px;
    line-height: 1.5;
}
.market-state-loss-head > strong {
    max-width: 52%;
    color: var(--text-secondary);
    font-size: 11px;
    font-weight: 650;
    line-height: 1.45;
    text-align: right;
    overflow-wrap: anywhere;
}
.market-state-loss-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 7px;
}
.market-state-loss-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 3px 9px;
    min-width: 0;
    padding: 8px 9px;
    border: 1px solid var(--market-line);
    border-left: 3px solid var(--market-line-strong, var(--market-line));
    background: var(--market-panel-muted);
}
.market-state-loss-label {
    display: grid;
    min-width: 0;
    gap: 1px;
}
.market-state-loss-label b {
    overflow: hidden;
    color: var(--text-primary);
    font-size: 11.5px;
    text-overflow: ellipsis;
    white-space: normal;
    overflow-wrap: anywhere;
}
.market-state-loss-label span {
    overflow: hidden;
    color: var(--text-muted);
    font-size: 9.5px;
    text-overflow: ellipsis;
    white-space: normal;
    overflow-wrap: anywhere;
}
.market-state-loss-return {
    align-self: center;
    color: var(--text-primary);
    font-size: 13px;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}
.market-state-loss-state {
    justify-self: start;
    color: var(--text-muted);
    font-size: 9.5px;
    font-weight: 650;
}
.market-state-loss-detail {
    display: flex;
    grid-column: 1 / -1;
    min-width: 0;
    flex-wrap: wrap;
    gap: 2px 7px;
    color: var(--text-muted);
    font-size: 9.5px;
    line-height: 1.45;
}
.market-state-loss-detail small {
    color: var(--market-amber);
}
.market-state-loss-row.is-controlled { border-left-color: var(--market-up); }
.market-state-loss-row.is-under_pressure { border-left-color: var(--market-amber); }
.market-state-loss-row.is-deteriorating { border-left-color: var(--market-down); }
.market-state-loss-row.is-unknown { border-left-style: dashed; }
.market-state-loss-row.is-controlled .market-state-loss-state { color: var(--market-up); }
.market-state-loss-row.is-under_pressure .market-state-loss-state { color: var(--market-amber); }
.market-state-loss-row.is-deteriorating .market-state-loss-state { color: var(--market-down); }
.market-state-surface {
    min-width: 0;
    padding: 15px;
}
.market-state-surface-head {
    margin-bottom: 8px;
    color: var(--text-primary);
    font-size: 13px;
    font-weight: 800;
}
.market-state-actions {
    display: grid;
    gap: 7px;
}
.market-state-actions-details {
    margin-top: 2px;
}
.market-state-actions-details > summary {
    display: flex;
    align-items: center;
    gap: 6px;
    padding: 7px 10px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel-muted);
    color: var(--text-secondary);
    font-size: 12px;
    font-weight: 600;
    cursor: pointer;
    list-style: none;
}
.market-state-actions-details > summary::-webkit-details-marker {
    display: none;
}
.market-state-actions-details > summary::after {
    content: '▾';
    margin-left: auto;
    font-size: 11px;
    color: var(--text-muted);
}
.market-state-actions-details[open] > summary::after {
    content: '▴';
}
.market-state-actions-details[open] > summary {
    margin-bottom: 8px;
}
.market-state-action {
    display: grid;
    grid-template-columns: 15px minmax(0, 1fr);
    gap: 5px;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.45;
}
.market-state-action i {
    color: #1576e8;
    font-style: normal;
    font-weight: 800;
}
@media (max-width: 1080px) {
    .market-state-map-grid { grid-template-columns: 1fr; }
    /* 右栏原本并排「段子卡片 + 结构观察」两块，段子卡片下线后只剩一块，
       两列栅格会把观察清单挤成半行、右侧留一个大空洞。保持单列整宽。 */
    .market-state-map-side { grid-template-columns: 1fr; }
}
@media (max-width: 760px) {
    .market-state-map-head { display: grid; gap: 8px; }
    .market-state-coverage { justify-self: start; }
    .market-state-map-main { grid-template-columns: 1fr; }
    .market-state-summary { padding: 0 0 12px; border-right: 0; border-bottom: 1px solid var(--market-line); }
    .market-state-canvas { height: 240px; min-height: 220px; }
    .market-state-evidence { grid-template-columns: minmax(0, 1fr); }
    .market-state-loss-grid { grid-template-columns: minmax(0, 1fr); }
    .market-state-loss-head { display: grid; }
    .market-state-loss-head > strong { max-width: none; text-align: left; }
    .market-state-map-side { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
    .market-state-evidence-row b {
        white-space: normal;
    }
    .market-state-loss-head > strong {
        line-height: 1.55;
    }
}
@media (max-width: 430px) {
    /* 底边距同样要留够横轴说明行，否则标签会压回 canvas 里；
       左带与上边距同步收窄，竖排标签宽度与 top 跟着变量走，不会脱钩。 */
    .market-state-plot {
        --market-state-y-band: 22px;
        --market-state-pad-top: 6px;
        padding: var(--market-state-pad-top) 8px var(--market-state-pad-bottom) var(--market-state-y-band);
    }

    .market-structure-context {
        padding: 10px 11px;
    }

    .market-structure-basis {
        grid-template-columns: 1fr;
        gap: 3px;
    }

    .market-structure-basis-label {
        white-space: normal;
    }

    .market-structure-basis-matrix[open] {
        margin-right: -11px;
        padding-right: 11px;
    }

    .market-structure-basis-table {
        min-width: 600px;
    }
}

/* ===========================================================================
   象限轨迹 / 段子指数三态 / 下一步观察条件 / 体检表为什么 / 周期信号分层
   颜色沿用本文件的既有约定：up(红)=正向，down(绿)=负向，amber=警示。
   =========================================================================== */

.market-state-marker:focus-visible,
.market-state-reading-bar:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: 2px;
}

/* 状态地图统一提示气泡。层级高于 marker(6)，低于本文件的浮层档
   （.market-plate-drawer 90 / .market-event-similar-modal 1200），
   否则会盖住抽屉与弹窗。fixed 定位，坐标由 JS 按锚点视口矩形算出。 */
.market-state-tooltip {
    position: fixed;
    z-index: 40;
    max-width: 260px;
    padding: 6px 9px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
    color: var(--text-primary);
    font-size: 11px;
    line-height: 1.5;
    white-space: pre-line;
    box-shadow: 0 6px 18px rgba(15, 23, 42, .18);
    pointer-events: none;
}
.market-state-tooltip[hidden] { display: none; }

.market-state-condition { display: grid; gap: 5px; }
.market-state-condition + .market-state-condition { margin-top: 11px; }
.market-state-condition-head {
    color: var(--text-muted);
    font-size: 11px;
    font-weight: 700;
}
.market-state-condition-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    gap: 8px;
    align-items: baseline;
    color: var(--text-secondary);
    font-size: 12px;
    line-height: 1.45;
}
.market-state-condition-row b { color: var(--text-primary); }
.market-state-condition-row em {
    color: var(--text-muted);
    font-size: 11px;
    font-style: normal;
}
.market-state-condition.is-up .market-state-condition-row.is-met b { color: var(--market-up); }
.market-state-condition.is-down .market-state-condition-row.is-met b { color: var(--market-down); }

.market-cycle-layers {
    display: grid;
    gap: 9px;
    margin-top: 11px;
}
.market-cycle-layer { display: grid; gap: 5px; }
.market-cycle-layer-head {
    display: flex;
    gap: 6px;
    align-items: baseline;
    color: var(--text-primary);
    font-size: 11px;
    font-weight: 800;
}
.market-cycle-layer-head em {
    color: var(--text-muted);
    font-size: 11px;
    font-style: normal;
    font-weight: 400;
}
.market-cycle-layer-rows { display: flex; gap: 6px; flex-wrap: wrap; }
.market-cycle-chip.is-risk {
    border-color: rgba(4, 120, 87, .3);
    background: var(--market-down-soft);
    color: var(--market-down);
}
.market-cycle-chip.is-support {
    border-color: rgba(220, 38, 38, .26);
    background: var(--market-up-soft);
    color: var(--market-up);
}

/* 修复既有截断：涨停生态条塞 6 个指标在一个窄栏里，每格正文只剩约 60px，
   而 20px 字号下的 "+2.50%" 需要约 66px，于是被 text-overflow 截成 "+2...."——
   数字被吃掉而用户看不出少了什么。这里只收紧该条的留白与字号，让读数完整显示。 */
#market-ecology-strip .market-metric-cell { padding: 12px 10px; }
#market-ecology-strip .market-metric-cell strong { font-size: 17px; }

/* ---- AI超级复盘（AI super replay workspace）---- */
.ai-replay-workspace {
    display: grid;
    gap: 16px;
    padding-top: 18px;
}

.ai-replay-workspace .market-inline-state {
    min-height: 320px;
}

.ai-replay-panel {
    display: flex;
    flex-direction: column;
    gap: 0;
    min-height: 560px;
    max-height: 720px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    overflow: hidden;
}

/* 能力边界声明：常驻在面板顶部，第一条消息之后也不消失。
   用偏冷的蓝灰而不是告警橙——这是说明性文字，不是需要用户处理的问题，
   染成警示色会让整页看起来处处是异常。 */
.ai-replay-boundary {
    padding: 9px 16px;
    border-bottom: 1px solid var(--market-line);
    background: rgba(44, 122, 191, .05);
    font-size: 12px;
    line-height: 1.55;
    color: var(--text-muted);
}
.ai-replay-boundary p { margin: 0; }
.ai-replay-boundary b { color: var(--market-ink); font-weight: 600; }
.ai-boundary-ask { color: var(--market-ink); }
.ai-boundary-limit { margin-top: 2px; }

.ai-replay-evidence-bar {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    padding: 10px 16px;
    border-bottom: 1px solid var(--market-line);
    background: var(--market-panel-muted);
    font-size: 12px;
}

.ai-evidence-date { font-weight: 600; color: var(--market-ink); margin-right: 6px; }
.ai-evidence-muted { color: var(--text-muted); }

/* 证据维度折叠：十个编号铺成一排是页面上最花的一块，收进一行摘要里。
   交易日、口径、异动条数留在摘要之外——读任何一条回答都要先看前两个。 */
.ai-evidence-details { display: inline-block; }
.ai-evidence-details > summary {
    font-size: 11.5px;
    color: var(--text-muted);
    cursor: pointer;
    list-style: none;
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.ai-evidence-details > summary::-webkit-details-marker { display: none; }
.ai-evidence-details > summary::before { content: '▸'; font-size: 10px; }
.ai-evidence-details[open] > summary::before { content: '▾'; }
.ai-evidence-details > summary:hover { color: var(--market-ink); }
.ai-evidence-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin-top: 6px;
    /* 折开后铺满整行：摘要行是 inline 的，不定宽会让这一块跟着缩成一列。 */
    flex-basis: 100%;
    width: 100%;
}

.ai-replay-messages {
    flex: 1 1 auto;
    /* flex 子项默认 min-height:auto，不加这行内部内容一高就把面板撑出 max-height，
       滚动条会落到面板外，标题栏跟着一起滚走。 */
    min-height: 0;
    overflow-y: auto;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 14px;
}

.ai-replay-empty { text-align: center; padding: 28px 12px; }
.ai-empty-note { color: var(--text-muted); font-size: 13px; max-width: 460px; margin: 0 auto 20px; line-height: 1.6; }

.ai-suggestion-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    max-width: 560px;
    margin: 0 auto;
}

.ai-suggestion-item {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 12px 14px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    cursor: pointer;
    text-align: left;
    transition: border-color .15s ease, transform .1s ease;
}
.ai-suggestion-item:hover { border-color: var(--market-accent, #0b5fd0); transform: translateY(-1px); }
.ai-suggestion-mark {
    flex: none;
    width: 30px; height: 30px;
    display: grid; place-items: center;
    border-radius: 8px;
    background: rgba(21, 118, 232, .1);
    color: #1576e8;
    font-weight: 700;
    font-size: 13px;
}
.ai-suggestion-copy { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ai-suggestion-copy strong { font-size: 13px; color: var(--market-ink); }
.ai-suggestion-copy small { font-size: 11.5px; color: var(--text-muted); }

.ai-msg { display: flex; gap: 10px; max-width: 92%; }
.ai-msg-user { align-self: flex-end; }
.ai-msg-assistant { align-self: flex-start; }
.ai-assistant-mark {
    flex: none;
    width: 28px; height: 28px;
    display: grid; place-items: center;
    border-radius: 50%;
    background: #1576e8;
    color: #fff;
    font-size: 11px;
    font-weight: 700;
}
.ai-bubble { padding: 10px 14px; border-radius: 8px; font-size: 13.5px; line-height: 1.65; }
.ai-bubble-user { background: #1576e8; color: #fff; border-bottom-right-radius: 4px; white-space: pre-wrap; }
.ai-bubble-assistant {
    background: var(--market-panel-muted);
    border: 1px solid var(--market-line);
    border-top-left-radius: 4px;
}
/* 正文由 renderMarkdown 产出真实块级结构（h3-h6/p/ul/ol），故不再用 pre-wrap：
   pre-wrap 会把块与块之间的换行再渲染一遍，段落间距会被撑成两三倍。 */
.ai-answer-text { white-space: normal; }
.ai-answer-text p { margin: 0 0 9px; }
.ai-answer-text p:last-child { margin-bottom: 0; }
.ai-answer-text h3,
.ai-answer-text h4,
.ai-answer-text h5,
.ai-answer-text h6 {
    margin: 14px 0 7px;
    font-size: 13.5px;
    font-weight: 700;
    color: #1576e8;
    line-height: 1.5;
}
.ai-answer-text h3:first-child,
.ai-answer-text h4:first-child { margin-top: 0; }
.ai-answer-text strong { font-weight: 700; color: #b45309; }
.ai-answer-text ul,
.ai-answer-text ol { margin: 0 0 9px; padding-left: 20px; }
.ai-answer-text li { margin-bottom: 4px; }
.ai-answer-text ul { list-style: disc; }
.ai-answer-text ol { list-style: decimal; }
.ai-answer-text code {
    padding: 1px 5px;
    border-radius: 4px;
    background: rgba(21, 118, 232, 0.08);
    font-size: 12.5px;
}
.ai-stream-cursor {
    display: inline-block;
    width: 8px;
    height: 14px;
    margin-left: 2px;
    vertical-align: -2px;
    background: #1576e8;
    animation: ai-cursor-blink 0.9s steps(2, start) infinite;
}
@keyframes ai-cursor-blink { to { visibility: hidden; } }
.ai-msg-refs { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 8px; align-items: center; }
.ai-ref-chip {
    display: inline-block;
    padding: 1px 8px;
    border-radius: 999px;
    background: rgba(21, 118, 232, .1);
    color: #1576e8;
    font-size: 11px;
    font-weight: 600;
}
.ai-msg-risks { margin-top: 8px; padding-top: 8px; border-top: 1px dashed var(--market-line); }
.ai-msg-risks p { margin: 3px 0 0; font-size: 12px; color: var(--market-amber, #b45309); }
.ai-msg-meta { margin-top: 6px; font-size: 11px; color: var(--text-muted); }

/* 依据 / 风险 / 耗时折进一行：它们是审计信息而非正文，默认展开时每条回答底下
   固定多出三四行灰字，一屏两条回答就全是这些。 */
.ai-msg-details { margin-top: 8px; border-top: 1px dashed var(--market-line); padding-top: 6px; }
.ai-msg-details > summary {
    font-size: 11.5px;
    color: var(--text-muted);
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    gap: 4px;
}
.ai-msg-details > summary::-webkit-details-marker { display: none; }
.ai-msg-details > summary::before { content: '▸'; font-size: 10px; }
.ai-msg-details[open] > summary::before { content: '▾'; }
.ai-msg-details > summary:hover { color: var(--market-ink); }
.ai-msg-details .ai-msg-meta { margin-top: 2px; }

/* 这两条不能折进 details：它们说的是「这条回答本身不成立」，用户必须先看到
   再决定读不读正文。用琥珀色边框块而非红色，是「打折读」而不是「出错了」。 */
.ai-msg-insufficient,
.ai-msg-truncated {
    margin-top: 8px;
    padding: 6px 10px;
    border-left: 3px solid var(--market-amber, #b45309);
    border-radius: 4px;
    background: rgba(180, 83, 9, .07);
    font-size: 12px;
    line-height: 1.5;
    color: var(--market-amber, #b45309);
}
.ai-msg-degraded { color: var(--market-amber, #b45309); font-size: 13px; }
.ai-pending-note { padding: 2px 4px; font-size: 12.5px; color: var(--text-muted); }
/* 证据包口径警告：数据为临时值、抓取时点等，属于「读这份证据时要打的折扣」，
   按提醒而非报错着色。前端封顶 3 条，超出折叠成一行「另有 N 条」——
   上游多报几条就能把消息区顶下去，正常状态下的页面反而更吵。 */
.ai-replay-warnings { padding: 6px 16px 0; }
.ai-replay-warnings p {
    margin: 0 0 3px;
    font-size: 12px;
    line-height: 1.5;
    color: var(--market-amber, #b45309);
}
.ai-replay-warnings .ai-warn-more { color: var(--text-muted); cursor: help; }

/* 复盘工具：命中率面板与「核对未完成计划」是次要动作，整块默认折叠。
   对账在后端没有调度器，只能由用户点；把入口留在工具栏而不是消息流里，
   避免用户以为它是自动的，同时又不和「问什么」抢视线。 */
.ai-replay-tools { border-top: 1px solid var(--market-line); background: var(--market-panel-muted); }
.ai-replay-tools > summary {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 7px 16px;
    font-size: 12px;
    color: var(--market-ink);
    cursor: pointer;
    list-style: none;
}
.ai-replay-tools > summary::-webkit-details-marker { display: none; }
.ai-replay-tools > summary::before { content: '▸'; font-size: 10px; color: var(--text-muted); }
.ai-replay-tools[open] > summary::before { content: '▾'; }
.ai-replay-tools > summary > span { font-size: 11.5px; color: var(--text-muted); }
.ai-replay-toolbar {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 0 16px 8px;
    flex-wrap: wrap;
}
.ai-tool-btn {
    padding: 5px 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    color: var(--market-ink);
    font-size: 12px;
    cursor: pointer;
}
.ai-tool-btn:hover:not(:disabled) { border-color: #1576e8; color: #1576e8; }
.ai-tool-btn:disabled { opacity: .55; cursor: default; }
.ai-tool-note { font-size: 11.5px; color: var(--text-muted); }

.ai-replay-hit-rate {
    margin: 8px 16px 0;
    padding: 10px 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
}
.ai-hit-empty { font-size: 12.5px; color: var(--text-muted); line-height: 1.6; }
.ai-hit-empty.is-warn { color: var(--market-amber, #b45309); }
.ai-hit-headline { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.ai-hit-rate { font-size: 22px; font-weight: 700; color: #1576e8; }
.ai-hit-detail { font-size: 12px; color: var(--text-muted); }
/* 未判定的条数单列：把它并进分母会把命中率系统性拉低，用户会误判 AI 的水平。 */
.ai-hit-pending {
    margin-top: 5px;
    font-size: 11.5px;
    color: var(--market-amber, #b45309);
}
.ai-hit-table {
    width: 100%;
    margin-top: 8px;
    border-collapse: collapse;
    font-size: 12px;
}
.ai-hit-table th,
.ai-hit-table td {
    padding: 4px 6px;
    text-align: right;
    border-bottom: 1px dashed var(--market-line);
}
.ai-hit-table th:first-child,
.ai-hit-table td:first-child { text-align: left; }
.ai-hit-table th { font-weight: 600; color: var(--text-muted); }

/* 结构化观察点：模型给的 2-3 条「明日观察点」在此勾选落库。落库前它只是一段
   散文，次日无法自动核对，所以这里必须给出可勾选、可追溯的形态。 */
.ai-obs-block {
    margin-top: 10px;
    padding-top: 9px;
    border-top: 1px dashed var(--market-line);
}
.ai-obs-title {
    display: flex;
    align-items: baseline;
    gap: 8px;
    flex-wrap: wrap;
    margin-bottom: 7px;
    font-size: 12.5px;
    font-weight: 700;
    color: #1576e8;
}
.ai-obs-title span { font-size: 11px; font-weight: 400; color: var(--text-muted); }
.ai-obs-item {
    padding: 7px 9px;
    margin-bottom: 6px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}
.ai-obs-item.is-selected { border-color: rgba(21, 118, 232, .45); background: rgba(21, 118, 232, .05); }
.ai-obs-head {
    display: flex;
    align-items: center;
    gap: 7px;
    flex-wrap: wrap;
    cursor: pointer;
    font-size: 12.5px;
}
.ai-obs-head code {
    padding: 1px 5px;
    border-radius: 4px;
    background: rgba(21, 118, 232, .1);
    font-size: 11.5px;
}
.ai-obs-direction {
    padding: 1px 7px;
    border-radius: 999px;
    font-size: 11px;
    font-style: normal;
    font-weight: 600;
}
.ai-obs-direction.is-up { background: rgba(220, 38, 38, .12); color: #dc2626; }
.ai-obs-direction.is-down { background: rgba(22, 163, 74, .12); color: #16a34a; }
.ai-obs-direction.is-neutral { background: rgba(100, 116, 139, .14); color: #475569; }
.ai-obs-threshold { font-size: 11px; font-style: normal; color: var(--text-muted); }
.ai-obs-premise { margin-top: 5px; font-size: 12.5px; line-height: 1.6; color: var(--market-ink); }
.ai-obs-condition { margin: 3px 0 0; font-size: 11.5px; line-height: 1.55; color: var(--text-muted); }
.ai-obs-condition span { margin-right: 5px; color: var(--market-amber, #b45309); }
.ai-obs-actions { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px; }
.ai-obs-save {
    padding: 6px 14px;
    border: none;
    border-radius: 8px;
    background: #1576e8;
    color: #fff;
    font-size: 12.5px;
    font-weight: 600;
    cursor: pointer;
}
.ai-obs-save:hover:not(:disabled) { background: #0b5fd0; }
.ai-obs-save:disabled { opacity: .5; cursor: default; }
.ai-obs-sync { margin: 0; font-size: 12px; color: #1576e8; }
.ai-obs-sync.is-warn { color: var(--market-amber, #b45309); }

.ai-replay-input-row {
    display: flex;
    gap: 10px;
    padding: 12px 16px;
    border-top: 1px solid var(--market-line);
    background: var(--market-panel-muted);
}
.ai-replay-input {
    flex: 1;
    padding: 10px 14px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    font-size: 13.5px;
    background: var(--market-panel);
    color: var(--market-ink);
}
.ai-replay-input:focus { outline: none; border-color: #1576e8; }
.ai-replay-send {
    padding: 10px 22px;
    border: none;
    border-radius: 8px;
    background: #1576e8;
    color: #fff;
    font-size: 13.5px;
    font-weight: 600;
    cursor: pointer;
}
.ai-replay-send:hover { background: #0b5fd0; }

.ai-replay-disclaimer {
    margin: 0;
    padding: 8px 16px;
    font-size: 11.5px;
    color: var(--text-muted);
    background: var(--market-panel-muted);
    border-top: 1px dashed var(--market-line);
}

@media (max-width: 720px) {
    .ai-suggestion-grid { grid-template-columns: 1fr; }
    .ai-msg { max-width: 100%; }
}

/* =========================================================================
   题材情绪矩阵（THEME EMOTION MATRIX）
   格子主读数是 0-100 情绪分；衰减日（无涨停）降透明度；大盘情绪行嵌表头。
   ========================================================================= */

.market-heat-cell i.is-up { color: #dc2626; }
.market-heat-cell i.is-down { color: #16a34a; }

.market-heat-cell.is-decay {
    opacity: .62;
    background: var(--market-panel-muted);
    border-style: dashed;
}

.market-heat-cell small {
    overflow: hidden;
    max-width: 100%;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.market-heat-cell em {
    overflow: hidden;
    max-width: 100%;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* 大盘情绪行：与题材矩阵同一时间轴的市场周期七档。 */
.market-rotation-marketrow th,
.market-rotation-marketrow td {
    padding: 4px !important;
    font-size: 10px;
    background: var(--market-panel-muted);
    border-top: 1px dashed var(--market-line);
}

.market-rotation-marketname {
    font-weight: 600;
    color: var(--text-muted);
    text-align: left;
}

.market-rotation-marketcell {
    text-align: center;
}

.market-rotation-marketcell b {
    font-size: 11.5px;
    color: var(--text-primary);
}

.market-rotation-marketcell small {
    display: block;
    color: var(--text-muted);
    font-size: 10px;
}

.market-rotation-marketcell i {
    font-size: 10px;
    font-style: normal;
}

.market-rotation-marketcell i.is-up { color: #dc2626; }
.market-rotation-marketcell i.is-down { color: #16a34a; }

/* 市场周期七档的左侧色条（与市场情绪页 CYCLE_STAGE_CLASSES 同语义）。 */
.market-cycle-ice { box-shadow: inset 3px 0 0 #60a5fa; }
.market-cycle-ignition { box-shadow: inset 3px 0 0 #34d399; }
.market-cycle-fermenting { box-shadow: inset 3px 0 0 #10b981; }
.market-cycle-climax { box-shadow: inset 3px 0 0 #f59e0b; }
.market-cycle-divergence { box-shadow: inset 3px 0 0 #fb923c; }
.market-cycle-ebbing { box-shadow: inset 3px 0 0 #94a3b8; }
.market-cycle-neutral { box-shadow: inset 3px 0 0 rgba(148, 163, 184, .45); }

/* 事件头条计数条。 */
.market-emotion-events {
    gap: 6px;
}

.market-emotion-events span.is-up { color: #dc2626; }
.market-emotion-events span.is-down { color: #16a34a; }
.market-emotion-events span.is-risk {
    color: #b45309;
    background: rgba(245, 158, 11, .14);
    border-radius: 4px;
    padding: 0 6px;
}
.market-emotion-events span.is-jump {
    color: #1576e8;
    background: rgba(21, 118, 232, .12);
    border-radius: 4px;
    padding: 0 6px;
}

.market-emotion-events-detail {
    display: block;
    margin-top: 6px;
    color: var(--text-muted);
    font-size: 10.5px;
    line-height: 1.5;
}

/* 题材名单元格：核心池徽章 / 池外标记 / 分数环比。 */
.market-rotation-noncore {
    margin-left: 5px;
    padding: 0 4px;
    border: 1px solid var(--market-line);
    border-radius: 3px;
    color: var(--text-muted);
    font-size: 10px;
}

.market-rotation-theme-button i {
    font-size: 10px;
    font-style: normal;
}

.market-rotation-theme-button i.is-up { color: #dc2626; }
.market-rotation-theme-button i.is-down { color: #16a34a; }

.market-rotation-score-note {
    margin: 0;
    padding: 8px 14px 12px;
    color: var(--text-muted);
    font-size: 10.5px;
    line-height: 1.5;
    border-top: 1px dashed var(--market-line);
}

[data-theme="dark"] .market-heat-cell.is-decay {
    background: rgba(148, 163, 184, .07);
}

/* ---- 事件线索 / 题材动态（event clue + topic dynamics workspace）----
 *
 * Design rules for this workspace (v4):
 *  - One centred column, 840px, declared on .clue-shell and nowhere else, so
 *    the header, toolbar, stream, rail and detail view share one right edge.
 *    The event board is a 电报 feed, not a dashboard: a narrower measure keeps
 *    the title, summary and "why it matters" line inside one reading sweep,
 *    the way 财联社 / 韭研公社 run their wires. The width lives here alone so
 *    the list and detail cannot drift out of line with the toolbar.
 *  - Events are rows, not boxes. No card frame, no radius, no shadow -- one
 *    hairline between entries and a clock rail on the left. The previous cut
 *    wrapped every row in a bordered panel and repeated the date on each one.
 *  - The stream is grouped by day (10月12日 星期一) with HH:MM in the rail, so
 *    the chronology is readable without parsing a timestamp per row.
 *  - The right rail is aggregation only: 题材热度, 最高分事件 and the local
 *    涨停/资金指纹 read. It is borderless text on the page background, so it
 *    never competes with the stream.
 *  - No KPI overview strip. Four summary numbers above a list were the
 *    dashboard look the reader asked us to drop; the same facts now live on
 *    the title line and in the rail.
 *  - Five type steps, declared once as --clue-fs-* below. The previous cut used
 *    ten sizes with five of them (10.5/11/11.5/12/12.5) packed into a 2px band,
 *    so a card carried five near-identical sizes and no visible hierarchy.
 *  - Two accents. Amber marks "updated today" and the discriminating score;
 *    every other label is muted grey. Both come from --market-* tokens so they
 *    follow the dark theme -- hardcoded #1576e8/#b45309 used to drop to
 *    3.26:1/3.56:1 on the dark panel, under the 4.5:1 AA floor.
 *  - Constant values are not rendered. lifecycle_stage is 'sprout' for all 1141
 *    topics and topic_type is 'relevance' for 1112 of them, so a badge showing
 *    either spends attention on nothing.
 */
.clue-shell {
    /* The whole type scale. --clue-fs-teal flips with the theme because the
       light and dark teals are 5.47:1 and 9.59:1 respectively against their
       own panel; one value cannot serve both. */
    --clue-fs-meta: 11px;
    --clue-fs-body: 13px;
    --clue-fs-title: 15px;
    --clue-fs-lead: 18px;
    --clue-fs-page: 22px;
    /* KPI numerals (detail stats). Kept separate from --clue-fs-page so the two
       can shrink independently on narrow screens. */
    --clue-fs-kpi: 20px;
    --clue-fs-teal: #1576e8;
    display: grid;
    gap: 18px;
    padding-top: 18px;
    max-width: 840px;
    margin-inline: auto;
}

[data-theme="dark"] .clue-shell {
    --clue-fs-teal: #6cb2f7;
}

.clue-head h2 {
    margin: 2px 0 6px;
    font-size: var(--clue-fs-page);
    font-weight: 700;
    color: var(--market-ink);
}

.clue-head p {
    margin: 0;
    max-width: 68ch;
    font-size: var(--clue-fs-body);
    line-height: 1.7;
    color: var(--text-muted);
}

.clue-kicker {
    color: var(--clue-fs-teal);
    font-size: var(--clue-fs-meta);
    font-weight: 800;
}

/* ---- toolbar ----
   Text tabs, not pill buttons. 事件线索 / 题材动态 are two views of one page,
   and the way 雪球 / 财联社 label view switches is an underlined text tab; the
   old pair of filled segmented controls made the mode switch look like a
   primary action and the filters like a second one of equal weight. */
.clue-toolbar {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
    padding-bottom: 2px;
    border-bottom: 1px solid var(--market-line);
}

.clue-toolbar-right {
    display: flex;
    align-items: center;
    gap: 10px;
    flex-wrap: wrap;
}

.clue-mode-tabs {
    display: inline-flex;
    align-items: baseline;
    gap: 18px;
}

.clue-mode-tabs button {
    position: relative;
    padding: 0 0 9px;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: var(--clue-fs-title);
    font-weight: 600;
    cursor: pointer;
    transition: color .15s ease;
}

.clue-mode-tabs button::after {
    content: '';
    position: absolute;
    right: 0;
    bottom: -1px;
    left: 0;
    height: 2px;
    background: transparent;
}

.clue-mode-tabs button:hover { color: var(--market-ink); }

.clue-mode-tabs button.active {
    color: var(--market-ink);
    font-weight: 700;
}

.clue-mode-tabs button.active::after { background: var(--market-ink); }

/* 筛选 popover: one trigger that names the current scope, one panel with the
   two groups. The old toolbar always showed all six filter buttons, which made
   the header read as a control panel before it read as a feed. */
.clue-filter { position: relative; }

.clue-filter-trigger {
    padding: 5px 11px;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
    color: var(--market-ink);
    font-size: var(--clue-fs-meta);
    cursor: pointer;
    white-space: nowrap;
}

.clue-filter-trigger:hover { border-color: var(--market-amber); color: var(--market-amber); }

.clue-filter-trigger:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: 1px;
}

.clue-filter-pop {
    position: absolute;
    top: calc(100% + 6px);
    right: 0;
    z-index: 8;
    display: grid;
    gap: 10px;
    min-width: 210px;
    padding: 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    box-shadow: 0 10px 28px rgba(15, 23, 42, .12);
}

.clue-filter-group {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
}

.clue-filter-label {
    flex-shrink: 0;
    min-width: 30px;
    font-size: var(--clue-fs-meta);
    font-weight: 700;
    color: var(--text-muted);
}

.clue-filter-group button {
    padding: 3px 9px;
    border: 1px solid transparent;
    border-radius: 5px;
    background: transparent;
    color: var(--text-muted);
    font-size: var(--clue-fs-meta);
    cursor: pointer;
}

.clue-filter-group button:hover { color: var(--market-ink); }

.clue-filter-group button.active {
    background: var(--market-panel-muted);
    color: var(--market-ink);
    font-weight: 650;
}

.clue-search input {
    width: 190px;
    padding: 5px 2px;
    border: 0;
    border-bottom: 1px solid var(--market-line);
    border-radius: 0;
    background: transparent;
    color: var(--market-ink);
    font-size: var(--clue-fs-body);
}

.clue-search input:focus {
    outline: none;
    border-bottom-color: var(--market-amber);
}

.clue-head-row {
    display: flex;
    align-items: baseline;
    gap: 12px;
    flex-wrap: wrap;
}

.clue-head-meta {
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.clue-muted { font-size: var(--clue-fs-meta); color: var(--text-muted); }

.clue-warning {
    display: grid;
    gap: 4px;
    padding: 9px 12px;
    border: 1px solid var(--market-amber-soft);
    border-left: 3px solid var(--market-amber);
    border-radius: 8px;
    background: var(--market-amber-soft);
    font-size: var(--clue-fs-body);
    color: var(--market-ink);
}

/* Loading is a skeleton in the list's own rhythm, so the page does not jump
   when the rows arrive. */
.clue-skeleton {
    display: grid;
    border-top: 1px solid var(--market-line);
}

.clue-skeleton-row {
    display: grid;
    gap: 9px;
    padding: 16px 2px;
    border-bottom: 1px solid var(--market-line);
}

.clue-skeleton-bar {
    height: 11px;
    border-radius: 4px;
    background: var(--market-panel-muted);
    animation: clue-pulse 1.4s ease-in-out infinite;
}

.clue-skeleton-bar.is-title { width: 46%; height: 15px; }
.clue-skeleton-bar.is-line { width: 88%; }
.clue-skeleton-bar.is-line-short { width: 62%; }
.clue-skeleton-bar.is-chips { width: 34%; height: 20px; }

@keyframes clue-pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: .45; }
}

@media (prefers-reduced-motion: reduce) {
    .clue-skeleton-bar { animation: none; }
}

.clue-state {
    padding: 34px 20px;
    border: 1px dashed var(--market-line);
    border-radius: 8px;
    text-align: center;
    font-size: var(--clue-fs-body);
    line-height: 1.8;
    color: var(--text-muted);
}

.clue-state-error { border-color: var(--market-up); color: var(--market-up); }

.clue-text-btn {
    border: 0;
    background: transparent;
    color: var(--market-amber);
    font-size: var(--clue-fs-body);
    cursor: pointer;
    text-decoration: underline;
}

/* ---- card list ----
   Rows, not boxes. A bordered card per entry put a frame around every item and
   a second rule above its footer, so the eye read two stacked rectangles per
   row and the list looked like a form. Financial lists separate entries with a
   hairline and let type and spacing do the grouping. */
.clue-list {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    border-top: 1px solid var(--market-line);
}

.clue-card {
    display: grid;
    gap: 8px;
    padding: 16px 2px;
    border-bottom: 1px solid var(--market-line);
    background: transparent;
}

/* Only a row that actually navigates reacts to the pointer. The hover tint used
   to be unconditional while `cursor: pointer` was set only on topic cards, so
   an event card lit up under the mouse and then did nothing -- the tint and the
   cursor contradicted each other. A hoverable row now also carries a left
   accent bar, so "this row is a link" is visible without moving the mouse. */
.clue-card-link {
    position: relative;
    cursor: pointer;
    padding-left: 12px;
    transition: background .12s ease;
}

.clue-card-link::before {
    content: '';
    position: absolute;
    top: 14px;
    bottom: 14px;
    left: 0;
    width: 2px;
    border-radius: 2px;
    background: transparent;
    transition: background .12s ease;
}

.clue-card-link:hover { background: var(--market-panel-muted); }
.clue-card-link:hover::before { background: var(--market-amber); }
.clue-card-link:hover .clue-card-title { color: var(--market-amber); }

.clue-card-link:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: -2px;
}

.clue-card-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
}

.clue-card-title {
    margin: 0;
    font-size: var(--clue-fs-title);
    font-weight: 650;
    line-height: 1.5;
    color: var(--market-ink);
}

.clue-card-when {
    display: flex;
    flex-shrink: 0;
    align-items: baseline;
    gap: 8px;
}

.clue-card-time { font-size: var(--clue-fs-meta); color: var(--text-muted); white-space: nowrap; }

/* The only two accents on a card. */
.clue-today {
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--market-amber-soft);
    color: var(--market-amber);
    font-size: var(--clue-fs-meta);
    font-weight: 600;
    white-space: nowrap;
}

/* Clamped to three lines rather than two: the summary is the only prose on the
   row and the column is now wide enough to hold a sentence, so cutting it at
   two lines was discarding text the layout had room for. */
.clue-card-summary {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
    margin: 0;
    max-width: 88ch;
    font-size: var(--clue-fs-body);
    line-height: 1.7;
    color: var(--text-muted);
}

.clue-chips { display: flex; flex-wrap: wrap; gap: 6px; }

.clue-chip {
    padding: 2px 9px;
    border-radius: 5px;
    background: var(--market-panel-muted);
    border: 1px solid var(--market-line);
    font-size: var(--clue-fs-body);
    color: var(--market-ink);
}

.clue-chip small { color: var(--text-muted); margin-left: 3px; }

/* A chip that navigates is marked at rest, not only on hover. Previously the
   only difference from a plain chip was `cursor` and a hover colour, so the
   one navigable element on an event card was invisible until the pointer
   happened to cross it.
   The mark is coloured *text* on the neutral chip, not a filled amber pill:
   filling all of them turned five chips per row into the heaviest thing on the
   card, which is the opposite of what this row needs -- the title is the
   entry point, the chips are a way out of it. */
.clue-chip-link {
    cursor: pointer;
    font-family: inherit;
    color: var(--market-amber);
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.clue-chip-link:hover {
    background: var(--market-amber);
    border-color: var(--market-amber);
    color: var(--market-panel);
}

.clue-chip-link:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: 1px;
}

/* "+N" is a control, not a label: the topics it counts were previously
   unreachable. It now expands the row's full chip list in place. */
.clue-chip-more {
    cursor: pointer;
    font-family: inherit;
    color: var(--text-muted);
    transition: border-color .15s ease, color .15s ease;
}

.clue-chip-more:hover { border-color: var(--market-ink); color: var(--market-ink); }

.clue-chip-more:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: 1px;
}

/* No rule above the footer: the row already has its own hairline, and a second
   line inside the row is what made each entry look like a form field. */
.clue-card-foot {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

.clue-foot-text { font-size: var(--clue-fs-meta); color: var(--text-muted); }

/* Score is the ranking signal, so it carries weight and a colour band. The unit
   is written out: a bare bold 76 next to "1 条线索" read as a second count, and
   the explanation only existed in a title tooltip that touch and keyboard users
   never see. */
.clue-score {
    display: inline-flex;
    align-items: baseline;
    gap: 4px;
    font-size: var(--clue-fs-lead);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    line-height: 1;
}

.clue-score small {
    font-size: var(--clue-fs-meta);
    font-weight: 500;
    color: var(--text-muted);
}

.clue-score.is-high { color: var(--market-amber); }
.clue-score.is-mid { color: var(--clue-fs-teal); }
.clue-score.is-low { color: var(--text-muted); }
.clue-score.is-none { color: var(--text-muted); font-weight: 500; font-size: var(--clue-fs-body); }

/* A topic's score saturates at 100 (68 of the top 100), so it is not the
   discriminator there; the event count is. Keep the score present but out of
   the way rather than painting two thirds of the board the same amber. */
.clue-score.is-plain {
    margin-left: auto;
    font-size: var(--clue-fs-meta);
    font-weight: 500;
    color: var(--text-muted);
}

.clue-count-lead {
    font-size: var(--clue-fs-lead);
    font-weight: 700;
    line-height: 1;
    color: var(--market-ink);
    font-variant-numeric: tabular-nums;
}

.clue-count-lead small {
    margin-left: 3px;
    font-size: var(--clue-fs-meta);
    font-weight: 400;
    color: var(--text-muted);
}

.clue-disclosure {
    margin: 0;
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
}

/* ---- board layout (v4) ----
   The event stream is a 电报 wire: one narrow reading column, one aggregation
   rail on the right. The rail is text, not a panel -- no border, no fill --
   so the eye treats it as annotation next to the wire rather than as a second
   column of content. 题材动态 keeps its two-column comparison grid, which is
   the one place side-by-side reading is the point. */
.clue-board {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 216px;
    align-items: start;
    gap: 26px;
}

/* The aside is first in the DOM (so the mobile fallback can stack it below via
   order), so its column is assigned explicitly. */
.clue-aside {
    grid-column: 2;
    grid-row: 1;
    position: sticky;
    top: 12px;
    display: grid;
    gap: 20px;
    min-width: 0;
}

.clue-aside-block {
    display: grid;
    gap: 8px;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
}

.clue-aside-block + .clue-aside-block {
    padding-top: 16px;
    border-top: 1px solid var(--market-line);
}

.clue-aside-title {
    margin: 0;
    font-size: var(--clue-fs-body);
    font-weight: 700;
    color: var(--market-ink);
}

.clue-aside-title small {
    display: block;
    margin-top: 2px;
    font-size: var(--clue-fs-meta);
    font-weight: 400;
    color: var(--text-muted);
}

.clue-aside-topics,
.clue-aside-events,
.clue-limit-list {
    margin: 0;
    padding: 0;
    list-style: none;
    display: grid;
    gap: 7px;
}

.clue-aside-topic {
    display: grid;
    grid-template-columns: minmax(0, 1fr) 22px;
    align-items: center;
    column-gap: 7px;
    row-gap: 2px;
}

.clue-aside-rank {
    grid-column: 1 / -1;
    font-size: var(--clue-fs-meta);
    font-weight: 700;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.clue-aside-topic .clue-aside-bar {
    grid-column: 1 / 2;
}

.clue-aside-topic .clue-aside-count {
    grid-column: 2 / 3;
    text-align: right;
}

.clue-aside-event {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 8px;
}

.clue-aside-name {
    overflow: hidden;
    border: 0;
    padding: 0;
    background: transparent;
    color: var(--market-ink);
    font-size: var(--clue-fs-meta);
    font-family: inherit;
    line-height: 1.5;
    text-align: left;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.clue-aside-name.is-clickable { cursor: pointer; }
.clue-aside-name.is-clickable:hover { color: var(--market-amber); text-decoration: underline; }
.clue-aside-name.is-clickable:focus-visible { outline: 2px solid var(--market-amber); outline-offset: 1px; }

.clue-aside-event .clue-aside-name { white-space: normal; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; }
.clue-aside-event-title { display: block; }

.clue-aside-bar {
    display: block;
    height: 4px;
    border-radius: 2px;
    background: var(--market-panel-muted);
}

.clue-aside-bar i {
    display: block;
    height: 100%;
    border-radius: 2px;
    background: var(--clue-fs-teal);
    opacity: .5;
}

.clue-aside-count {
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.clue-aside-note {
    margin: 2px 0 0;
    font-size: 10.5px;
    line-height: 1.5;
    color: var(--text-muted);
}

/* 今日涨停 / 资金指纹 -- local aggregation, stated as such. */
.clue-limit-row {
    display: grid;
    gap: 3px;
    padding-bottom: 6px;
    border-bottom: 1px dashed var(--market-line);
}

.clue-limit-row:last-child { padding-bottom: 0; border-bottom: 0; }

.clue-limit-head {
    display: flex;
    align-items: baseline;
    gap: 6px;
}

.clue-limit-industry {
    min-width: 0;
    overflow: hidden;
    font-size: var(--clue-fs-meta);
    font-weight: 650;
    color: var(--market-ink);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.clue-limit-pct {
    margin-left: auto;
    font-size: var(--clue-fs-meta);
    font-weight: 700;
    font-variant-numeric: tabular-nums;
}

.clue-limit-count {
    flex-shrink: 0;
    font-size: 10.5px;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.clue-limit-stocks {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 8px;
}

.clue-limit-stock {
    font-size: 10.5px;
    color: var(--text-muted);
}

.clue-limit-stock i {
    font-style: normal;
    font-variant-numeric: tabular-nums;
}

.clue-limit-pct.is-up,
.clue-limit-stock i.is-up { color: var(--market-up); }

.clue-limit-pct.is-down,
.clue-limit-stock i.is-down { color: var(--market-down); }

/* ---- the wire: day groups + rows ---- */
.clue-day + .clue-day { margin-top: 6px; }

.clue-day-head {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin: 18px 0 0;
    padding-bottom: 6px;
    font-size: var(--clue-fs-body);
    font-weight: 700;
    color: var(--market-ink);
}

.clue-day-head small {
    font-size: var(--clue-fs-meta);
    font-weight: 400;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.clue-list {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
    border-top: 1px solid var(--market-line);
}

.clue-card-event {
    display: grid;
    grid-template-columns: 44px minmax(0, 1fr) auto;
    align-items: start;
    gap: 12px;
    min-width: 0;
    padding: 11px 2px;
    border-bottom: 1px solid #eceff3;
    border-radius: 0;
    background: transparent;
    cursor: pointer;
    transition: background .12s ease;
}

[data-theme="dark"] .clue-card-event { border-bottom-color: var(--market-line); }

.clue-card-event:hover { background: var(--market-panel-muted); }

.clue-card-event:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: -2px;
}

.clue-card-time-rail {
    padding-top: 2px;
    font-size: 12px;
    font-weight: 600;
    color: #9aa3af;
    font-variant-numeric: tabular-nums;
    text-align: right;
    white-space: nowrap;
}

[data-theme="dark"] .clue-card-time-rail { color: var(--text-muted); }

.clue-card-main {
    display: grid;
    gap: 6px;
    min-width: 0;
}

.clue-card-event .clue-card-title {
    margin: 0;
    font-size: 15px;
    font-weight: 600;
    line-height: 1.45;
    color: #1f2328;
}

[data-theme="dark"] .clue-card-event .clue-card-title { color: var(--market-ink); }

.clue-card-summary {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 1;
    overflow: hidden;
    margin: 0;
    max-width: none;
    font-size: 12.5px;
    line-height: 1.6;
    color: #6b7280;
}

[data-theme="dark"] .clue-card-summary { color: var(--text-muted); }

.clue-card-summary.is-expanded {
    display: block;
    overflow: visible;
    -webkit-line-clamp: unset;
}

.clue-summary-toggle {
    justify-self: start;
    padding: 0;
    border: 0;
    background: transparent;
    color: var(--market-amber);
    font-size: 11px;
    font-family: inherit;
    cursor: pointer;
}

.clue-summary-toggle:hover { text-decoration: underline; }

.clue-summary-toggle:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: 1px;
}

.clue-reason-line {
    display: flex;
    flex-wrap: wrap;
    gap: 4px 12px;
    margin: 0;
    font-size: 11px;
    line-height: 1.5;
    color: #9aa3af;
}

[data-theme="dark"] .clue-reason-line { color: var(--text-muted); }

.clue-reason-line span { white-space: nowrap; }

.clue-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    min-height: 0;
    align-content: start;
}

.clue-card-event .clue-chip {
    padding: 1px 7px;
    border: 0;
    border-radius: 3px;
    background: var(--market-panel-muted);
    font-size: 11px;
    line-height: 1.6;
    color: var(--text-muted);
}

.clue-card-event .clue-chip-link { color: var(--market-amber); }

.clue-card-event .clue-chip-link:hover {
    background: var(--market-amber);
    color: var(--market-panel);
}

.clue-card-event .clue-chip-more { color: var(--text-muted); }

.clue-score-dot {
    padding-top: 2px;
    font-size: 12px;
    font-weight: 600;
    line-height: 1.2;
    font-variant-numeric: tabular-nums;
}

.clue-score-dot.is-high { color: var(--market-amber); }
.clue-score-dot.is-mid { color: var(--clue-fs-teal); }
.clue-score-dot.is-low,
.clue-score-dot.is-none,
.clue-score-dot.is-plain { color: #9aa3af; }

[data-theme="dark"] .clue-score-dot.is-low,
[data-theme="dark"] .clue-score-dot.is-none,
[data-theme="dark"] .clue-score-dot.is-plain { color: var(--text-muted); }

/* Topic cards keep the hover tint and the left accent, since the whole card
   navigates. Only the pointer feedback differs from the wire. */
.clue-card-link {
    position: relative;
    cursor: pointer;
    padding-left: 12px;
    transition: background .12s ease;
}

.clue-card-link::before {
    content: '';
    position: absolute;
    top: 12px;
    bottom: 12px;
    left: 0;
    width: 3px;
    border-radius: 2px;
    background: transparent;
    transition: background .12s ease;
}

.clue-card-link:hover { background: var(--market-panel-muted); }
.clue-card-link:hover::before { background: var(--market-amber); }
.clue-card-link:hover .clue-card-title { color: var(--market-amber); }

.clue-card-link:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: -2px;
}

/* Aside link flash: a brief background pulse marks the row a jump landed on. */
.clue-card.is-flashed {
    animation: clue-flash 1.6s ease-out;
}

@keyframes clue-flash {
    0%, 30% { background: var(--market-amber-soft); }
    100% { background: transparent; }
}

@media (prefers-reduced-motion: reduce) {
    .clue-card.is-flashed { animation: none; }
}

/* 题材动态 keeps the comparison grid: topics, unlike events, really are read
   side by side. It falls back to one column in the narrow query below. */
.clue-list-cols {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    border-top: 0;
}

.clue-list-cols .clue-card {
    padding: 14px 15px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    transition: border-color .15s ease, background .15s ease, box-shadow .15s ease;
}

.clue-list-cols .clue-card-link:hover {
    border-color: var(--market-amber);
    background: var(--market-panel);
    box-shadow: none;
}

.clue-card-head {
    align-items: flex-start;
}

.clue-list-cols .clue-card-title {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    overflow: hidden;
    line-height: 1.45;
}

.clue-list-cols .clue-card-summary {
    -webkit-line-clamp: 2;
    max-width: none;
    line-height: 1.6;
}

/* No rule above the foot in row mode: the row already has its own hairline. */
.clue-card-foot {
    min-height: 0;
    padding-top: 0;
    border-top: 0;
}

/* ---- row drawer: the whole story without leaving the wire ---- */
.clue-drawer { position: fixed; inset: 0; z-index: 60; }

.clue-drawer[hidden] { display: none; }

.clue-drawer-scrim {
    position: absolute;
    inset: 0;
    background: rgba(15, 23, 42, .38);
}

.clue-drawer-panel {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    display: grid;
    align-content: start;
    gap: 14px;
    width: min(460px, 92vw);
    padding: 18px 20px 28px;
    overflow-y: auto;
    border-left: 1px solid var(--market-line);
    background: var(--market-panel);
    box-shadow: -12px 0 32px rgba(15, 23, 42, .16);
    animation: clue-drawer-in .18s ease-out;
}

@keyframes clue-drawer-in {
    from { transform: translateX(24px); opacity: 0; }
    to { transform: translateX(0); opacity: 1; }
}

@media (prefers-reduced-motion: reduce) {
    .clue-drawer-panel { animation: none; }
}

.clue-drawer-head {
    display: flex;
    align-items: baseline;
    gap: 10px;
}

.clue-drawer-time {
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.clue-drawer-head .clue-score { margin-left: auto; }

.clue-drawer-close {
    border: 0;
    padding: 0 2px;
    background: transparent;
    color: var(--text-muted);
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}

.clue-drawer-close:hover { color: var(--market-ink); }

.clue-drawer-close:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: 1px;
}

.clue-drawer-title {
    margin: 0;
    font-size: var(--clue-fs-lead);
    font-weight: 700;
    line-height: 1.45;
    color: var(--market-ink);
}

.clue-drawer-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
}

.clue-drawer-section {
    display: grid;
    gap: 6px;
    padding-top: 12px;
    border-top: 1px solid var(--market-line);
}

.clue-drawer-section h4 {
    margin: 0;
    font-size: var(--clue-fs-meta);
    font-weight: 700;
    color: var(--text-muted);
}

.clue-drawer-summary {
    margin: 0;
    font-size: var(--clue-fs-body);
    line-height: 1.8;
    color: var(--market-ink);
}

/* ---- detail view ---- */
.clue-detail {
    display: grid;
    gap: 14px;
}

.clue-detail-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 10px;
}

.clue-detail-back {
    padding: 5px 11px;
    border: 1px solid var(--market-line);
    border-radius: 7px;
    background: var(--market-panel);
    color: var(--market-ink);
    font-size: var(--clue-fs-body);
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}
.clue-detail-back:hover { border-color: var(--market-amber); color: var(--market-amber); }

.clue-detail-caption { font-size: var(--clue-fs-meta); color: var(--text-muted); }

.clue-detail-head {
    display: grid;
    gap: 7px;
    padding-bottom: 14px;
    border-bottom: 1px solid var(--market-line);
}

.clue-detail-head-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 12px;
    flex-wrap: wrap;
}

.clue-detail-title {
    margin: 0;
    font-size: var(--clue-fs-page);
    font-weight: 700;
    line-height: 1.3;
    color: var(--market-ink);
}

.clue-detail-badges {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 8px;
}

.clue-detail-summary {
    margin: 0;
    max-width: 88ch;
    font-size: var(--clue-fs-body);
    line-height: 1.75;
    color: var(--text-muted);
}

/* ---- tabs ---- */
.clue-detail-tabs {
    display: flex;
    flex-wrap: wrap;
    gap: 2px;
    border-bottom: 1px solid var(--market-line);
}

.clue-detail-tabs button {
    display: inline-flex;
    align-items: baseline;
    gap: 5px;
    padding: 8px 13px;
    border: 0;
    border-bottom: 2px solid transparent;
    background: transparent;
    color: var(--text-muted);
    font-size: var(--clue-fs-body);
    font-weight: 600;
    cursor: pointer;
    transition: color .15s ease, border-color .15s ease;
}

.clue-detail-tabs button:hover { color: var(--market-ink); }

.clue-detail-tabs button small {
    font-size: var(--clue-fs-meta);
    font-weight: 500;
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.clue-detail-tabs button.active {
    color: var(--market-ink);
    border-bottom-color: var(--market-amber);
}

.clue-detail-tabs button.active small { color: var(--market-amber); }

.clue-detail-panel { display: grid; gap: 14px; }

/* A panel is a plain block: no border, no shadow. Content carries the page. */
.clue-panel { display: grid; gap: 10px; }

.clue-panel-title {
    margin: 0;
    font-size: var(--clue-fs-title);
    font-weight: 700;
    color: var(--market-ink);
}

.clue-panel-title small {
    margin-left: 6px;
    font-size: var(--clue-fs-meta);
    font-weight: 400;
    color: var(--text-muted);
}

.clue-lede {
    margin: 0;
    max-width: 88ch;
    font-size: var(--clue-fs-body);
    line-height: 1.85;
    color: var(--market-ink);
}

.clue-fact { display: grid; gap: 3px; }

.clue-fact-label {
    font-size: var(--clue-fs-meta);
    font-weight: 700;
    color: var(--text-muted);
}

.clue-fact p {
    margin: 0;
    max-width: 88ch;
    font-size: var(--clue-fs-body);
    line-height: 1.75;
    color: var(--market-ink);
}

.clue-empty {
    padding: 18px;
    border: 1px dashed var(--market-line);
    border-radius: 8px;
    text-align: center;
    font-size: var(--clue-fs-body);
    color: var(--text-muted);
}

.clue-note { margin: 0; font-size: var(--clue-fs-meta); color: var(--text-muted); }

/* ---- timeline ---- */
.clue-timeline { margin: 0; padding: 0; list-style: none; display: grid; gap: 16px; }

.clue-timeline-group {
    display: grid;
    grid-template-columns: 54px minmax(0, 1fr);
    gap: 12px;
}

.clue-timeline-date {
    display: grid;
    align-content: start;
    gap: 1px;
    padding-top: 2px;
    text-align: right;
}

.clue-timeline-date span {
    font-size: var(--clue-fs-body);
    font-weight: 700;
    color: var(--market-ink);
    font-variant-numeric: tabular-nums;
}

.clue-timeline-date small { font-size: var(--clue-fs-meta); color: var(--text-muted); }

.clue-timeline-items {
    display: grid;
    gap: 8px;
    padding-left: 12px;
    border-left: 1px solid var(--market-line);
}

.clue-timeline-item {
    display: grid;
    gap: 5px;
    padding: 10px 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.clue-timeline-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.clue-timeline-title {
    font-size: var(--clue-fs-title);
    font-weight: 600;
    line-height: 1.5;
    color: var(--market-ink);
}

.clue-timeline-time { flex-shrink: 0; font-size: var(--clue-fs-meta); color: var(--text-muted); }

.clue-timeline-summary {
    margin: 0;
    max-width: 88ch;
    font-size: var(--clue-fs-body);
    line-height: 1.7;
    color: var(--text-muted);
}

.clue-timeline-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 10px;
}

.clue-timeline-note { margin: 0; font-size: var(--clue-fs-meta); color: var(--text-muted); }

/* ---- 题材表格：a real table ---- */
.clue-sheet-intro { display: grid; gap: 6px; }

.clue-sheet-trigger {
    display: flex;
    align-items: baseline;
    gap: 8px;
    font-size: var(--clue-fs-body);
    line-height: 1.7;
    color: var(--market-ink);
}

.clue-sheet-trigger span {
    flex-shrink: 0;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--market-amber-soft);
    color: var(--market-amber);
    font-size: var(--clue-fs-meta);
    font-weight: 600;
}

.clue-sheet-subtitle {
    margin: 0;
    max-width: 88ch;
    font-size: var(--clue-fs-body);
    line-height: 1.7;
    color: var(--text-muted);
}

.clue-table-wrap {
    overflow-x: auto;
    border: 1px solid var(--market-line);
    border-radius: 8px;
}

/* table-layout: fixed is what makes the column widths below authoritative.
   Without it the auto algorithm treats `width` as a suggestion and the 代码
   column absorbs slack that belongs to 入选逻辑. */
.clue-table {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    font-size: var(--clue-fs-body);
}

.clue-table th,
.clue-table td {
    padding: 8px 12px;
    text-align: left;
    vertical-align: top;
}

.clue-table thead th {
    position: sticky;
    top: 0;
    z-index: 1;
    border-bottom: 1px solid var(--market-line);
    background: var(--market-panel-muted);
    font-size: var(--clue-fs-meta);
    font-weight: 700;
    color: var(--text-muted);
    white-space: nowrap;
}

.clue-table tbody tr + tr td { border-top: 1px solid var(--market-line); }

.clue-table tbody tr:hover td { background: var(--market-panel-muted); }

/* The group row sticks just under the sticky thead, so a scrolled table keeps
   both the column headers and the 产业链环节 label in view. Its top offset must
   stay in sync with the thead's height: thead th is
   8px+8px padding + one 11px line (~15px) + 1px border ≈ 33px. */
.clue-group-row th {
    position: sticky;
    top: 33px;
    z-index: 2;
    padding: 7px 12px;
    border-top: 1px solid var(--market-line);
    border-bottom: 1px solid var(--market-line);
    background: var(--market-panel-muted);
    font-weight: 700;
    text-align: left;
}

.clue-table-group:first-of-type .clue-group-row th { border-top: 0; }

.clue-group-name { font-size: var(--clue-fs-body); color: var(--market-ink); }

.clue-group-tag {
    margin-left: 8px;
    padding: 1px 6px;
    border-radius: 4px;
    border: 1px solid var(--market-line);
    background: var(--market-panel);
    font-size: var(--clue-fs-meta);
    font-weight: 500;
    color: var(--text-muted);
}

.clue-group-count {
    float: right;
    font-size: var(--clue-fs-meta);
    font-weight: 500;
    color: var(--text-muted);
}

/* With fixed layout these are exact. 代码 is six digits; it needs ~76px and no
   more, and every pixel it takes comes out of 入选逻辑. */
.clue-col-name { width: 32%; }
.clue-col-code { width: 78px; }

.clue-stock-name {
    font-size: var(--clue-fs-body);
    font-weight: 650;
    color: var(--market-ink);
}

/* The source's own emphasis label -- the highest-signal text in the row. */
.clue-stock-flag {
    display: inline-block;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--market-amber-soft);
    color: var(--market-amber);
    font-size: var(--clue-fs-meta);
    font-weight: 600;
}

.clue-col-code {
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

.clue-col-logic { line-height: 1.7; color: var(--text-muted); }

.clue-table-note { margin: 0; font-size: var(--clue-fs-meta); color: var(--text-muted); }

/* ---- 题材关系：传导路径 + 关系分组 ---- */
.clue-rel-section { display: grid; gap: 8px; }

.clue-rel-section + .clue-rel-section { margin-top: 6px; }

.clue-rel-heading {
    margin: 0;
    font-size: var(--clue-fs-title);
    font-weight: 700;
    color: var(--market-ink);
}

.clue-rel-heading small {
    margin-left: 6px;
    font-size: var(--clue-fs-meta);
    font-weight: 400;
    color: var(--text-muted);
}

.clue-paths { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }

.clue-path {
    display: grid;
    gap: 5px;
    padding: 10px 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.clue-path-flow {
    display: flex;
    align-items: baseline;
    flex-wrap: wrap;
    gap: 8px;
}

.clue-path-node {
    font-size: var(--clue-fs-body);
    font-weight: 650;
    color: var(--market-ink);
}

.clue-path-node.is-target { color: var(--market-amber); }

.clue-path-arrow { font-size: var(--clue-fs-body); color: var(--text-muted); }

.clue-path-weight {
    margin-left: auto;
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
}

.clue-path-text { margin: 0; font-size: var(--clue-fs-body); line-height: 1.7; color: var(--text-muted); }

.clue-rel-groups { display: grid; gap: 12px; }

.clue-rel-group { display: grid; gap: 6px; }

.clue-rel-group-title { display: flex; align-items: baseline; gap: 8px; }

.clue-rel-kind {
    padding: 1px 7px;
    border-radius: 4px;
    border: 1px solid var(--market-line);
    background: var(--market-panel-muted);
    font-size: var(--clue-fs-meta);
    font-weight: 600;
    color: var(--text-muted);
}

.clue-rel-kind.is-catalysts { border-color: var(--market-amber); color: var(--market-amber); background: var(--market-amber-soft); }
.clue-rel-kind.is-risks { border-color: var(--market-up); color: var(--market-up); background: var(--market-up-soft); }

.clue-rel-items { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }

.clue-rel-item { display: grid; gap: 3px; }

.clue-rel-item-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; }

.clue-rel-chip {
    padding: 2px 8px;
    border-radius: 5px;
    border: 1px solid var(--market-line);
    background: var(--market-panel-muted);
    color: var(--market-ink);
    font-size: var(--clue-fs-body);
    font-family: inherit;
}

/* A clickable relation chip is marked at rest, for the same reason as
   .clue-chip-link: cursor and hover alone leave it indistinguishable from a
   label until the pointer lands on it. Coloured text rather than a filled
   pill, so a group of them does not outweigh the heading above. */
.clue-rel-chip.is-clickable {
    cursor: pointer;
    color: var(--market-amber);
    transition: background .15s ease, color .15s ease, border-color .15s ease;
}

.clue-rel-chip.is-clickable:hover {
    background: var(--market-amber);
    border-color: var(--market-amber);
    color: var(--market-panel);
}

.clue-rel-chip.is-clickable:focus-visible {
    outline: 2px solid var(--market-amber);
    outline-offset: 1px;
}

.clue-rel-item-text {
    margin: 0;
    padding-left: 2px;
    font-size: var(--clue-fs-body);
    line-height: 1.7;
    color: var(--text-muted);
}

/* Co-mention ranking: name, proportional bar, count. The bar is what makes the
   ordering legible at a glance; without it the list is just numbers. */
.clue-comentions { margin: 0; padding: 0; list-style: none; display: grid; gap: 2px; }

.clue-comention {
    display: grid;
    grid-template-columns: 140px minmax(0, 1fr) 40px;
    align-items: center;
    gap: 12px;
    padding: 5px 0;
}

.clue-comention-name {
    overflow: hidden;
    border: 0;
    padding: 0;
    background: transparent;
    color: var(--market-ink);
    font-size: var(--clue-fs-body);
    font-family: inherit;
    text-align: left;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.clue-comention-name.is-clickable { cursor: pointer; }
.clue-comention-name.is-clickable:hover { color: var(--market-amber); text-decoration: underline; }

/* The track is capped so a bar reads as a magnitude, not as a rule across the
   page: at full width a 100% bar looks like a divider, and the shortest one
   still looked long. */
.clue-comention-bar {
    display: block;
    max-width: 260px;
    height: 6px;
    border-radius: 3px;
    background: var(--market-panel-muted);
}

.clue-comention-bar i {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: var(--clue-fs-teal);
    opacity: .55;
}

.clue-comention-count {
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
    font-variant-numeric: tabular-nums;
    text-align: right;
}

.clue-relations { display: flex; flex-wrap: wrap; gap: 6px; }

.clue-relation {
    display: inline-flex;
    align-items: baseline;
    gap: 7px;
    padding: 4px 10px;
    border: 1px solid var(--market-line);
    border-radius: 7px;
    background: var(--market-panel);
    color: var(--market-ink);
    font-size: var(--clue-fs-body);
    font-family: inherit;
    cursor: pointer;
    transition: border-color .15s ease;
}

.clue-relation:hover { border-color: var(--market-amber); }

.clue-relation-name { font-weight: 600; }

.clue-relation-type {
    padding: 1px 5px;
    border-radius: 4px;
    background: var(--market-panel-muted);
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
}

.clue-relation-conf { font-size: var(--clue-fs-meta); color: var(--text-muted); font-variant-numeric: tabular-nums; }

/* ---- 产业地图 / 产业链 ---- */
.clue-map { display: grid; gap: 10px; }

.clue-map-layer { display: grid; gap: 5px; }

.clue-map-layer-name {
    font-size: var(--clue-fs-meta);
    font-weight: 700;
    color: var(--text-muted);
}

.clue-map-nodes { margin: 0; padding: 0; list-style: none; display: grid; gap: 6px; }

.clue-map-node {
    display: grid;
    gap: 3px;
    padding: 9px 11px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.clue-map-node.is-key { border-left: 3px solid var(--market-amber); }

.clue-map-node-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }

.clue-map-node-name { font-size: var(--clue-fs-body); font-weight: 650; color: var(--market-ink); }

.clue-map-node-link {
    margin-left: auto;
    border: 0;
    background: transparent;
    color: var(--text-muted);
    font-size: var(--clue-fs-meta);
    font-family: inherit;
    cursor: pointer;
    text-decoration: underline;
}
.clue-map-node-link:hover { color: var(--market-amber); }

.clue-map-node-text { margin: 0; font-size: var(--clue-fs-body); line-height: 1.7; color: var(--text-muted); }

.clue-map-parents { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; margin-top: 4px; }

.clue-chain-level { display: grid; gap: 6px; }
.clue-chain-level + .clue-chain-level { margin-top: 10px; }

.clue-chain-level-name { margin: 0; font-size: var(--clue-fs-meta); font-weight: 700; color: var(--text-muted); }

.clue-chain-segment { display: grid; gap: 4px; padding-left: 10px; border-left: 1px solid var(--market-line); }

.clue-chain-segment-name { font-size: var(--clue-fs-body); font-weight: 650; color: var(--market-ink); }

.clue-chain-companies { margin: 0; padding: 0; list-style: none; display: grid; gap: 4px; }

.clue-chain-company { display: grid; gap: 2px; }

.clue-chain-company-name { font-size: var(--clue-fs-body); font-weight: 600; color: var(--market-ink); }

.clue-chain-company-reason { font-size: var(--clue-fs-body); line-height: 1.7; color: var(--text-muted); }

/* ---- 深度资料索引 ---- */
.clue-articles { display: grid; gap: 8px; }

.clue-article {
    display: grid;
    gap: 5px;
    padding: 11px 13px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
}

.clue-article-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 10px;
}

.clue-article-title { font-size: var(--clue-fs-body); font-weight: 650; color: var(--market-ink); }

.clue-article-date { flex-shrink: 0; font-size: var(--clue-fs-meta); color: var(--text-muted); }

.clue-article-summary { margin: 0; font-size: var(--clue-fs-body); line-height: 1.7; color: var(--text-muted); }

.clue-article-meta { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px; }

.clue-locked {
    padding: 1px 6px;
    border-radius: 4px;
    border: 1px solid var(--market-line);
    font-size: var(--clue-fs-meta);
    color: var(--text-muted);
}

/* 详情页：把结论、规模和分组关系固定成可扫读的节奏。 */
.clue-detail-head {
    gap: 12px;
    padding: 4px 0 16px;
}

.clue-detail-title {
    letter-spacing: 0;
}

.clue-detail-summary {
    max-width: 92ch;
    line-height: 1.7;
}

.clue-detail-stats {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 1px;
    overflow: hidden;
    margin-top: 4px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-line);
}

.clue-detail-stat {
    display: grid;
    gap: 2px;
    padding: 10px 12px;
    background: var(--market-panel-muted);
}

.clue-detail-stat strong {
    color: var(--market-ink);
    font-size: var(--clue-fs-kpi);
    line-height: 1.1;
    font-variant-numeric: tabular-nums;
}

.clue-detail-stat span {
    color: var(--market-ink);
    font-size: var(--clue-fs-body);
    font-weight: 650;
}

.clue-detail-stat small {
    color: var(--text-muted);
    font-size: var(--clue-fs-meta);
}

.clue-detail-tabs {
    position: sticky;
    top: 0;
    z-index: 3;
    gap: 4px;
    padding-top: 4px;
    background: var(--market-panel);
}

.clue-detail-tabs button {
    padding: 9px 13px;
    border-radius: 6px 6px 0 0;
}

.clue-detail-panel {
    gap: 18px;
}

.clue-panel-title {
    display: flex;
    align-items: baseline;
    gap: 6px;
    padding-bottom: 8px;
    border-bottom: 1px solid var(--market-line);
}

.clue-timeline {
    gap: 18px;
}

.clue-timeline-group {
    grid-template-columns: 68px minmax(0, 1fr);
    gap: 14px;
}

.clue-timeline-items {
    gap: 7px;
}

.clue-timeline-item {
    padding: 11px 13px;
    border-radius: 7px;
}

.clue-timeline-summary {
    line-height: 1.6;
}

.clue-table-wrap {
    max-height: 620px;
    overflow: auto;
}

.clue-table th,
.clue-table td {
    padding: 10px 12px;
}

.clue-table tbody tr:hover td {
    background: var(--market-panel-muted);
}

.clue-group-row {
    position: sticky;
    top: 35px;
    z-index: 2;
}

.clue-col-name { width: 28%; }

.clue-rel-groups {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

.clue-rel-group {
    align-content: start;
    padding: 11px 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.clue-rel-items {
    gap: 8px;
}

.clue-rel-item {
    padding-bottom: 8px;
    border-bottom: 1px solid var(--market-line);
}

.clue-rel-item:last-child {
    padding-bottom: 0;
    border-bottom: 0;
}

.clue-paths {
    grid-template-columns: repeat(2, minmax(0, 1fr));
}

.clue-path {
    min-width: 0;
    padding: 11px 12px;
}

.clue-map {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 14px;
}

.clue-map-layer {
    align-content: start;
    padding: 11px 12px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-muted);
}

.clue-map-parents {
    grid-column: 1 / -1;
}

@media (max-width: 900px) {
    .clue-shell {
        padding-top: 12px;
    }

    .clue-toolbar {
        align-items: stretch;
    }

    .clue-toolbar-right {
        width: 100%;
    }

    .clue-search,
    .clue-search input {
        min-width: 0;
        width: 100%;
    }

    .clue-detail-stats {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }

    /* Narrow screens: the synthesis rail moves below the stream and spans it,
       the two-column comparison grids fall back to one column. */
    .clue-board {
        grid-template-columns: minmax(0, 1fr);
    }

    .clue-aside {
        position: static;
        order: 2;
    }

    .clue-list {
        order: 1;
    }

    .clue-list,
    .clue-list-cols,
    .clue-rel-groups,
    .clue-paths,
    .clue-map {
        grid-template-columns: minmax(0, 1fr);
    }

    .clue-list-cols .clue-card {
        padding: 13px 2px;
        border: 0;
        border-bottom: 1px solid var(--market-line);
        border-radius: 0;
        background: transparent;
    }

    .clue-map-parents {
        grid-column: auto;
    }
}

@media (max-width: 560px) {
    .clue-shell {
        gap: 13px;
        padding: 10px 0 18px;
    }

    /* Narrow screens scale the type by overriding the tokens, so every element
       referencing them shrinks together instead of each rule restating a px
       value (which is how the raw sizes crept back in). */
    .clue-shell {
        --clue-fs-page: 20px;
        --clue-fs-kpi: 19px;
    }

    .clue-toolbar-right,
    .clue-mode-tabs,
    .clue-filter {
        width: 100%;
    }

    .clue-mode-tabs {
        justify-content: space-between;
    }

    .clue-mode-tabs button {
        flex: 1 1 auto;
        padding-inline: 8px;
        text-align: center;
    }

    .clue-filter-pop {
        right: auto;
        left: 0;
        width: min(320px, 92vw);
    }

    .clue-card-head,
    .clue-card-event,
    .clue-detail-head-row,
    .clue-timeline-head {
        display: grid;
        gap: 6px;
    }

    .clue-card-time-rail {
        text-align: left;
    }

    .clue-card-when,
    .clue-detail-badges {
        justify-content: flex-start;
    }

    .clue-timeline-group {
        grid-template-columns: 1fr;
        gap: 6px;
    }

    .clue-timeline-date {
        display: flex;
        align-items: baseline;
        justify-content: space-between;
        text-align: left;
    }

    .clue-timeline-items {
        padding-left: 0;
        border-left: 0;
    }

    .clue-table {
        min-width: 680px;
    }
}

/* ---- 实时消息（realtime message workspace）—— QQ 群聊式消息流 ---- */
/*
 * 单列、时间线、气泡。三条既有约定必须保持：
 *   1. 不重新定义其他页面拥有的类名（`.realtime-toggle` 属于策略页的「实时解析」开关）。
 *   2. 配色只用本页的 --market-* 变量，跟随深浅色主题。
 *   3. 正文来自外部消息，样式上不能给它任何能撑破布局的自由（长串、长词必须换行）。
 *
 * 布局：主列 + 定宽右栏。
 *
 * 2026-10-12 版式复审（用户反馈「左边太宽、右边太窄」）：
 *
 * 原来主列是 `1fr`、右栏固定 320px。1912 视口下主列被一路撑到 1276px
 * （正文一行近 90 个汉字，读起来是一堵墙），右栏始终 320px —— 归档正文只剩
 * 17 个汉字一行，四个体裁按钮连带未读角标直接顶出可视区被裁掉。
 *
 * 现在两栏都跟着视口走，按「消息流 : 工具栏 ≈ 1.2 : 1」分配，并各自封顶：
 *   主列 minmax(0, 1fr)                     —— 吃掉剩余空间
 *   右栏 minmax(340px, min(45%, 640px))     —— 越宽越宽，但最多 640px
 * 320px 这个写死的值没了：1440 视口右栏约 491px，1912 视口约 617px，
 * 右栏正文一行从 17 个汉字升到 35 个上下，体裁栏也不再被裁掉。
 */
.realtime-shell {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(340px, min(45%, 640px));
    align-items: start;
    gap: 18px;
    padding-top: 18px;
    /* 两个窗口的共同高度，见下面那段说明。定义在这里而不是散在两个窗口里，是
       因为上一次就是同一个数字在两处各写一遍、然后慢慢分叉的。 */
    --realtime-window-height: calc(100vh - 150px);
}


/*
 * 两个窗口等高。
 *
 * 之前两栏各按自己的内容高度收缩：左栏的高由 .realtime-stream 的
 * max-height: calc(100vh - 250px) 决定，右栏由 .realtime-aside-window 的
 * max-height: calc(100vh - 140px) 决定 —— 两个上限本来就不一样；再加上
 * .realtime-shell 是 align-items: start，于是消息多时左栏长、消息少时右栏短，
 * 同一排看上去是两个不相干的东西。用户指出「左右两边的框应该高低一样」。
 *
 * 所以两栏共用一个**显式** height，而不是各自的上限：高度定了，内部各自滚动。
 * 高度只在这里出现一次，是刻意的 —— 上一次就是同一个数字在两个地方各写一遍、
 * 于是慢慢分叉的。
 */
/*
 * 左栏：窗口定高之后，消息区填满剩下的高度并自己滚。
 *
 * 原来 .realtime-stream 自带 max-height: calc(100vh - 250px) 和
 * min-height: 420px —— 那是它在没有定高的窗口里自己撑出高度的办法。窗口定高
 * 之后上限归窗口，min-height 也必须让位：420px 会在矮视口上把左栏顶得比右栏高，
 * 正好是这次要消除的那个现象。
 */
#realtime-body {
    display: flex;
    flex-direction: column;
    flex: 1 1 auto;
    min-height: 0;
}

.realtime-column {
    display: grid;
    gap: 14px;
    min-width: 0;
}

.realtime-aside {
    min-width: 0;
}

/*
 * 右半边：一个窗口，和左边的消息面板同构。
 *
 * 早先是三张上下堆叠的卡片（分类 / 搜索 / AI 分析），每张自带标题和说明，读起来
 * 像三块拼在一起的东西。用户指出「应该像左侧一样的窗口」—— 左栏好看是因为它只有
 * 一个头、一个内容区，右栏照这个结构做。
 *
 * 窗口吸顶：检索和对话是「随时想用就用」的工具，跟着消息流一起滚出屏幕就失去了
 * 意义。sticky 而不是 fixed，窄屏下它自然回到文档流里（见文件末尾的窄屏规则）。
 *
 * 高度对齐左栏：左栏的 .realtime-stream 用 calc(100vh - Npx) 限高，右栏用同一个
 * 上限，两个窗口看起来才是同一排的东西。
 */
.realtime-aside-window {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    overflow: hidden;
    position: sticky;
    top: 18px;
    /* 与左栏同高。见 .realtime-shell 上那段说明：之前这两个数不一样
       (100vh - 140px vs 100vh - 250px)，加上 align-items: start，两栏各按自己
       的内容高度收缩，消息多时左栏长、消息少时右栏短。
       max-height 与 height 同值，是因为 sticky 定位需要一个确定的高度。 */
    height: var(--realtime-window-height);
    max-height: var(--realtime-window-height);
}

/* 窗口头部，与 .realtime-chat-head 同构：头像 + 标题 + 口径。 */
.realtime-aside-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--market-panel-muted);
}

.realtime-aside-avatar {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    border-radius: 8px;
    /* 蓝而不是琥珀：这一栏是可交互的工具（检索/筛选/问答），按「颜色即语义」
       的规则归主色；琥珀留给未读与提醒。 */
    background: var(--market-brand-soft);
    color: var(--market-brand);
    font-size: 14px;
    font-weight: 600;
    line-height: 30px;
    text-align: center;
}

.realtime-aside-identity {
    min-width: 0;
}

.realtime-aside-title {
    margin: 0;
    font-size: 13.5px;
    font-weight: 600;
    color: var(--text-strong, var(--text));
}

.realtime-aside-meta {
    margin-top: 1px;
    font-size: 11.5px;
    color: var(--text-secondary);
}

/* 归档能力说明：与卖点同级，说明右栏「为什么值得留在这里查」。 */
.realtime-aside-archive {
    margin-top: 1px;
    font-size: 11.5px;
    color: var(--text-secondary);
}

/*
 * 一排紧凑功能按钮。
 *
 * 全部塞进一行，用竖线分组而不是分卡片 —— 这些按钮是同一个工具的不同旋钮，拆成
 * 几块只会让每个旋钮看起来像独立功能。窄屏会换行（见文件末尾），但不会隐藏任何
 * 一个：分类和窗口是这个页面的功能，不是装饰。
 */
.realtime-aside-toolbar {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 6px;
    padding: 8px 12px;
    border-bottom: 1px solid var(--market-line);
}

.realtime-chip-group {
    display: inline-flex;
    gap: 4px;
}

.realtime-chip-sep {
    width: 1px;
    height: 14px;
    background: var(--market-line);
    margin: 0 2px;
}

/* 单个旋钮。刻意做小：它们是筛选条件，不是主操作按钮。 */
.realtime-chip {
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
    font-size: 12px;
    line-height: 1;
    padding: 5px 9px;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}

.realtime-chip:hover {
    background: var(--market-panel-muted);
    color: var(--text);
}

.realtime-chip.is-active {
    border-color: var(--market-brand);
    background: var(--market-brand-soft);
    color: var(--market-brand);
    font-weight: 600;
}

/* 按钮上的条数。刻意做得比标签小一号并压低对比度：它是提示，不是按钮的主要
   内容 —— 四个按钮各带一个数字，数字和标签一样重就会盖过标签本身。 */
/*
 * 体裁筛选这一排。
 *
 * 它是独立的一行而不是接在视图按钮后面 —— 两者回答的是不同的问题：「看哪一块」
 * 对应视图，「看哪一类内容」对应体裁。挤在一行里读者会以为点体裁会切视图。
 */
.realtime-aside-genres {
    gap: 8px;
    background: var(--market-panel-muted);
}

/*
 * 体裁按钮组必须能换行。
 *
 * 原来 .realtime-chip-group 是 inline-flex 且不换行，四个体裁按钮 + 未读角标
 * 在 320px 的右栏里放不下，最后一个「其他内容」直接被裁在可视区外 —— 线上
 * 截图里只剩「其他内」半个词。右栏现在宽了，但窄视口仍会回到 300px，所以
 * 这里不能只靠宽度兜底：放不下就换行，永远不裁字。
 */
.realtime-aside-genres .realtime-chip-group {
    flex-wrap: wrap;
    row-gap: 4px;
}

/* 「包含其他内容」：文字按钮，不做成和筛选同级的旋钮 —— 它是那一档的整体取舍，
   放在筛选右侧、右对齐，读起来就是「在四档之外多做一个决定」。
   margin-left: auto 让它在同一行时贴右；换行时它自己独占一行，仍然是右对齐。 */
.realtime-chip-link {
    border: none;
    background: transparent;
    color: var(--text-muted);
    font-size: 11.5px;
    padding: 4px 2px;
    cursor: pointer;
    text-decoration: underline;
    text-underline-offset: 2px;
    white-space: nowrap;
    margin-left: auto;
}

/*
 * 体裁按钮上的未读数，视觉照抄左栏「实时消息」那个红色角标。
 *
 * 做成同一套是有理由的：两处回答的是同一个问题 —— 「有多少是我还没看过的」。
 * 左栏那个是绝对定位挂在导航项右上角的，而体裁按钮是一行排布的，按钮本身的边框
 * 也要留给选中态，所以这里是行内的一颗小药丸：同样的红、同样的圆角、同样的
 * 10.5px 白字，99 条以上同样显示 99+。
 */
.realtime-chip-badge {
    display: inline-block;
    min-width: 16px;
    margin-left: 5px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--market-up, #dc2626);
    color: #fff;
    font-size: 10.5px;
    font-style: normal;
    font-weight: 600;
    line-height: 15px;
    text-align: center;
    vertical-align: 1px;
}

.realtime-chip-link:hover {
    color: var(--market-amber);
}

/* 消息流底部的「继续加载」。给足点击面积但压低视觉重量：它是一次翻页，
   不是这个窗口的主操作。 */
.realtime-group-more {
    display: flex;
    justify-content: center;
    padding: 10px 0 4px;
}

.realtime-btn-secondary {
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel-muted);
    color: var(--text-muted);
    font-size: 12px;
    line-height: 1;
    padding: 7px 14px;
    cursor: pointer;
    transition: color 0.15s ease, border-color 0.15s ease;
}

.realtime-btn-secondary:hover:not(:disabled) {
    color: var(--market-amber);
    border-color: var(--market-amber);
}

.realtime-btn-secondary:disabled {
    opacity: 0.55;
    cursor: default;
}

/* 条目里的体裁小标签。读者扫一眼就知道这条属于哪一类，不用回头去对照上面的
   筛选按钮。做成一颗浅蓝药丸：它是分类信息，按「颜色即语义」归主色，不再用
   色块去区分档位 —— 四个档位各给一个颜色，读者记不住，还会和涨跌红绿打架。

   这一行现在只有它一个元素，所以不再需要左边距：留着会让徽章比下面的正文
   缩进 6px，两栏的左缘对不齐。 */
.realtime-genre-tag {
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--market-brand-soft);
    font-size: 11px;
    font-weight: 600;
    color: var(--market-brand);
    white-space: nowrap;
}

/* 链接类消息：标题 + 摘要。标题略重、摘要压低一档并夹在次要色里 ——
   读者先看标题决定要不要点，摘要是辅助判断，不该和标题一样重。 */
.realtime-bubble-title {
    margin: 0 0 4px;
    font-size: 13.5px;
    line-height: 1.5;
    font-weight: 600;
    color: var(--text-strong, var(--text));
    overflow-wrap: anywhere;
    word-break: break-word;
    /* 研报标题动辄三四十个字，firstLine 只削从正文取标题的那条路径；归档里
       自带的 title 没有长度上限，所以这里再夹一道，两行足够读者判断方向，
       也不会让一条长标题把整屏气泡挤下去。 */
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.realtime-bubble-summary {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.6;
    color: var(--text-secondary);
    /* 摘要限高：标题 + 三行摘要足以判断价值，铺满整块气泡反而变成噪音。 */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

/* 图片消息那一行说明。比摘要更轻，因为它是口径不是内容：读者需要知道
   这行标题是从图里识读出来的，而不是群里有人打的一句标题。 */
.realtime-bubble-note {
    margin: 3px 0 0;
    font-size: 11px;
    line-height: 1.5;
    color: var(--text-muted);
    opacity: 0.8;
}

/* 内容区：唯一可滚动的部分，头部和按钮排固定。 */
.realtime-aside-body {
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 10px 12px 12px;
}

.realtime-panel-state {
    padding: 10px 2px;
    font-size: 12px;
    line-height: 1.6;
    color: var(--text-muted);
}

.realtime-panel-state.is-error {
    color: var(--market-down, #dc2626);
}

.realtime-panel-state small {
    display: inline-block;
    margin-top: 4px;
    opacity: 0.85;
}

.realtime-panel-hint {
    margin: 8px 0 0;
    font-size: 11.5px;
    line-height: 1.5;
    color: var(--text-muted);
}

/* 「继续加载」失败时的那一行。必须与普通提示区别开：它说的是「这一页没拿到」，
   而上面的消息仍然有效 —— 同样的灰色会让读者以为整屏都没了。 */
.realtime-panel-hint.is-error {
    color: var(--market-down, #c76a5a);
    text-align: center;
}

/* 搜索行。只有输入框 —— 时间窗和分类已经移到顶部按钮排，不再各占一行。 */
.realtime-search-bar {
    margin-bottom: 10px;
}

.realtime-search-input {
    width: 100%;
    box-sizing: border-box;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-soft, transparent);
    color: var(--text);
    font-size: 12.5px;
    padding: 7px 10px;
}

.realtime-search-input:focus {
    outline: none;
    border-color: var(--market-brand);
}

/* 搜索结果区。高度由 .realtime-aside-body 统一约束，这里不再单独限高 ——
   两层滚动容器会让人分不清在滚哪一个。 */
.realtime-search-pane {
    min-width: 0;
}

/*
 * 群视图：和左边消息流同一套气泡。
 *
 * 复用 .realtime-stream / .realtime-message / .realtime-bubble，所以两栏的排版、
 * 字号、换行、链接样式天然一致 —— 用户要的就是「和左群一样」。
 *
 * 这里只覆盖两件必须不同的事：
 *   1. 高度由 .realtime-aside-body 统一约束，不再自己限高（两层滚动容器会让人
 *      分不清在滚哪一个）；
 *   2. 右栏只有半页宽，头像位和间距收窄一点，否则气泡可用宽度被吃掉太多。
 *
 * 第 1 条写的是 `.realtime-stream.realtime-stream-aside` 而不是
 * `.realtime-stream-aside`，这不是为了好看。基类 .realtime-stream 带着
 * `max-height: calc(100vh - 250px)` 和 `overflow-y: auto`，而它在文件里出现得
 * **更晚**；两个单类选择器优先级相同，后写的赢，于是右栏照样套上了基类的限高和
 * 滚动 —— 外面 .realtime-aside-body 滚一层，里面这条列表再滚一层，读者看到的
 * 就是两条并排的滑条，而代码里那句"不再自己限高"从未生效。写成两个类之后与顺序
 * 无关，这条覆盖才真的成立。
 */
.realtime-stream.realtime-stream-aside {
    max-height: none;
    overflow: visible;
    min-height: 0;
    padding: 0;
}

.realtime-stream-aside .realtime-message {
    /* 右栏只有 320px：时间列按「跨日 MM-DD HH:MM」定宽 78px —— 右栏没有日期
       分隔线，跨日的那一段必须自己带上日期，列宽就得容得下它。窄一点会让
       日期折行，宽一点会吃掉正文。 */
    grid-template-columns: 78px minmax(0, 1fr);
    column-gap: 10px;
    padding: 10px 0;
}

/* 右栏的时间戳左对齐：定宽列已经保证内容列的左缘是直的，文字跟着列走即可。 */
.realtime-stream-aside .realtime-message-time {
    font-size: 11px;
}

/* 右栏比左栏窄，图片按容器宽度收。320px 是给左栏那个宽气泡定的上限，搬进
   右栏会让一条图吃掉小半屏，读者连着看两条就得往回滚。 */
.realtime-stream-aside .realtime-bubble-image {
    max-height: 220px;
}

/* 群视图顶部的条数。用一行小字而不是大字：它是这一路的规模提示，
   读者真正要看的是下面的消息。 */
.realtime-group-count {
    margin-bottom: 8px;
    font-size: 11.5px;
    color: var(--text-secondary);
}







/* AI 对话。
 *
 * 用气泡区分提问和回答（和左边消息流同一套视觉语言，读者不需要学第二套），
 * 但气泡更紧凑 —— 右栏宽度只有半页，左栏那种大内边距在这里会挤掉内容。
 */
.realtime-chat-thread {
    display: flex;
    flex-direction: column;
    gap: 10px;
    min-width: 0;
}

.realtime-chat-turn {
    display: flex;
    min-width: 0;
}

/* 提问靠右，回答靠左。这是聊天界面的通用约定，靠对齐方向就能分清谁说的，
   不需要额外的「我 / 助手」标签。 */
.realtime-chat-turn.is-user {
    justify-content: flex-end;
}

.realtime-chat-bubble {
    max-width: 100%;
    min-width: 0;
    border-radius: 8px;
    padding: 8px 11px;
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--text);
    background: var(--market-panel-muted);
    border: 1px solid var(--market-line);
    /* 消息正文与模型输出都可能含长串，不能让它们撑破半页宽的面板。 */
    overflow-wrap: anywhere;
    word-break: break-word;
}

.realtime-chat-turn.is-user .realtime-chat-bubble {
    background: var(--market-brand-soft);
    border-color: color-mix(in srgb, var(--market-brand) 45%, transparent);
    color: var(--text-strong, var(--text));
}

.realtime-chat-text {
    margin: 0;
    white-space: pre-wrap;
}

/* 结论先行：回答的第一段单独成块。
 *
 * 刻意只用左边一条竖线 + 略加粗，不给底色也不放大字号。这个面板只有半页宽，
 * 一旦把结论做成卡片，读者注意力全在那个框上，剩下的铺垫和依据反而没人读 ——
 * 结论要的是「被先读到」，不是「被当成另一块内容」。 */
.realtime-chat-lead {
    margin: 0 0 9px;
    padding: 1px 0 1px 9px;
    border-left: 2px solid var(--market-brand);
}

/* 「结论」这个标签写在竖线顶部上方，弱到几乎只是注解。 */
.realtime-chat-lead-tag {
    display: block;
    margin-bottom: 2px;
    font-size: 10px;
    font-weight: 600;
    letter-spacing: 0.04em;
    color: var(--market-brand);
    opacity: 0.9;
}

/* 结论正文。与下面的正文同字号同颜色，只靠那条竖线区分 —— 字号差一档就会读成
 * 「小标题 + 正文」的另一种排版，反而把「这是判断」这件事说小了。 */
.realtime-chat-lead-body {
    font-size: inherit;
    line-height: 1.65;
    color: var(--text-strong, var(--text));
    font-weight: 500;
    white-space: pre-wrap;
}

.realtime-chat-lead-body p {
    margin: 0;
    white-space: normal;
}

/* tools 模式的回答是 Markdown（标题、表格、列表、加粗），所以正文里会出现这些
   元素。段落和表格用 white-space: normal —— 继承 pre-wrap 会把每个换行都当硬换行，
   表格和段落之间会多出空行。 */
.realtime-chat-text p {
    margin: 0 0 7px;
    white-space: normal;
}

.realtime-chat-text p:last-child {
    margin-bottom: 0;
}

.realtime-chat-text h5 {
    margin: 10px 0 5px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-strong, var(--text));
    white-space: normal;
}

.realtime-chat-text h5:first-child {
    margin-top: 0;
}

.realtime-chat-text ul {
    margin: 0 0 7px;
    padding-left: 16px;
    white-space: normal;
}

.realtime-chat-text li {
    margin-bottom: 3px;
}

/* 表格：模型会用表格列热度排序。宽了就横向滚动，不要把气泡撑破。 */
.realtime-chat-text table {
    display: block;
    width: 100%;
    margin: 0 0 8px;
    border-collapse: collapse;
    overflow-x: auto;
    font-size: 11.5px;
    white-space: normal;
}

.realtime-chat-text th,
.realtime-chat-text td {
    padding: 3px 7px;
    border: 1px solid var(--market-line);
    text-align: left;
    white-space: nowrap;
}

.realtime-chat-text th {
    font-weight: 600;
    color: var(--text-strong, var(--text));
    background: color-mix(in srgb, var(--market-line) 22%, transparent);
}

.realtime-chat-text code {
    padding: 1px 4px;
    border-radius: 3px;
    background: color-mix(in srgb, var(--market-line) 30%, transparent);
    font-size: 11px;
}

/* 这一轮检索了什么。检索词本身就是信息：看到「混合键合」「算力租赁」能判断覆盖面，
   只看到「热度榜」就知道它没往下挖。 */
.realtime-chat-tools {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px;
    margin: 0 0 7px;
}

.realtime-chat-tools-label {
    font-size: 11px;
    color: var(--text-muted);
}

.realtime-chat-tool {
    padding: 1px 6px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    font-size: 10.5px;
    line-height: 1.5;
    color: var(--text-muted);
}

/* 流式进行中的检索行。标签带一个呼吸点：检索阶段实测 28-44 秒，静态文字会让人
   怀疑卡死了；呼吸动画成本极低（透明度），又不像转圈那样抢注意力。 */
.realtime-chat-tools.is-streaming .realtime-chat-tools-label::after {
    content: '';
    display: inline-block;
    width: 5px;
    height: 5px;
    margin-left: 5px;
    border-radius: 50%;
    background: var(--market-amber);
    vertical-align: 1px;
    animation: realtime-stream-pulse 1.2s ease-in-out infinite;
}

@keyframes realtime-stream-pulse {
    0%, 100% { opacity: 0.25; }
    50% { opacity: 1; }
}

/* 流式正文：写了一半的 Markdown 不套完整渲染（半截表格/标题会闪），
   以 pre-wrap 纯文本呈现，结束后一次性切换成渲染好的结构。 */
.realtime-chat-text.is-streaming {
    white-space: pre-wrap;
    color: var(--text);
}

/* 失败或不可用时的说明。用琥珀色而不是红色：这些是「这次没拿到」，不是错误。 */
.realtime-chat-note {
    margin: 0;
    color: var(--market-amber);
}

/* 这一轮实际覆盖的范围。一行小字放在正文上方 —— 它决定读者怎么读下面的话：
   一份「覆盖 1 天」的分析不能用来回答「最近三天怎么样」。 */
.realtime-chat-scope {
    margin: 0 0 6px;
    font-size: 11px;
    color: var(--text-muted);
}

.realtime-chat-typing {
    color: var(--text-muted);
}

.realtime-chat-citations {
    margin-top: 8px;
    padding-top: 7px;
    border-top: 1px dashed var(--market-line);
}

.realtime-chat-citations h5 {
    margin: 0 0 4px;
    font-size: 11px;
    font-weight: 600;
    color: var(--text-muted);
}

/* 引用改成 <ol>（语义上是「有序依据」），但序号由 .realtime-citation-ordinal 自己
    画。必须把原生 marker 关掉，否则同一个引用会出现两个编号。 */
.realtime-chat-citations ul,
.realtime-chat-citations ol {
    margin: 0;
    padding-left: 0;
    list-style: none;
    font-size: 11.5px;
    line-height: 1.55;
    color: var(--text-muted);
}

.realtime-chat-citations li {
    margin-bottom: 3px;
}

/* 「依据 3 条线索」里那个条数。弱化到接近正文灰 —— 它是补充信息，不是标题。
    原来「引用线索」四个字和条数同样重，读起来像一条并列的结论。 */
.realtime-chat-citations-n {
    font-weight: 400;
    color: var(--text-muted);
    opacity: 0.8;
}

/* 引用线索：编号做成按钮，点开取原文。
 *
 * 编号本身单独看不构成信息（82783 是什么没人知道），所以它不是装饰文字而是入口 ——
 * 下划线加手型，让读者知道可以点。 */
.realtime-citation-toggle {
    padding: 1px 0;
    border: none;
    background: none;
    font: inherit;
    color: var(--market-accent, #1576e8);
    text-decoration: underline;
    text-underline-offset: 2px;
    cursor: pointer;
}

.realtime-citation-toggle:hover {
    color: var(--text);
}

/* 展开状态。原来是在编号前加一个 ● 当「已看过」的记号，但编号现在由上面那个序号
    徽标承担，两个记号并排会互相干扰。改成给整颗按钮一层极浅的底 —— 展开时正下方
    就摆着原文，状态其实已经不需要额外符号了，这层底只是让「哪几条我展开过」一眼可见。 */
.realtime-citation-toggle[aria-expanded="true"] {
    padding: 1px 5px;
    border-radius: 4px;
    background: color-mix(in srgb, var(--market-accent, #1576e8) 10%, transparent);
    text-decoration: none;
}

/* 依据的序号。跟 raw_feed_id 分开排版：序号是给人顺着读的，id 是给接口认的，
    两者挤在同一行同一个字号里，读者会以为 1827 是一个整体编号。 */
.realtime-citation-ordinal {
    display: inline-block;
    min-width: 15px;
    margin-right: 5px;
    padding: 0 3px;
    border-radius: 3px;
    background: var(--market-panel-muted);
    color: var(--text-muted);
    font-size: 10px;
    font-weight: 600;
    line-height: 15px;
    text-align: center;
    text-decoration: none;
    vertical-align: 1px;
}

/* 展开的原文。用左边框而不是整块底色：读者要能分清哪段是模型写的、哪段是消息原文。 */
.realtime-citation-body {
    margin: 4px 0 6px 2px;
    padding: 5px 8px;
    border-left: 2px solid var(--market-line);
    background: var(--surface-subtle, rgba(0, 0, 0, 0.02));
}

.realtime-citation-body .realtime-bubble-text {
    margin: 0;
    font-size: 11.5px;
    line-height: 1.6;
    color: var(--text);
    white-space: pre-wrap;
    word-break: break-word;
}

.realtime-citation-time {
    display: block;
    margin-bottom: 3px;
    font-size: 10.5px;
    color: var(--text-muted);
}

.realtime-citation-pending,
.realtime-citation-failed {
    font-size: 11.5px;
    color: var(--text-muted);
}

.realtime-citation-failed {
    color: var(--market-warn, #b45309);
}

/* 空对话的开场。
 *
 * 这里现在只有三个可点的问题，别的东西都被撤掉了。
 *
 * r6 的「回答取自已筛出 · …」是**错的**（AI 分析的请求体里没有 genre，MCP 也不按
 * 体裁过滤），r7 的「近 3 天共 667 条」是接口的返回而不是用户的决定依据。两样都不是
 * 读者此刻要判断的事，而它们把这半页宽的开场占满了。剩下的三个问题是可点的，点了
 * 就问出去，所以值得占这个位置。 */
.realtime-chat-intro p {
    margin: 0 0 8px;
    font-size: 12.5px;
    line-height: 1.65;
    color: var(--text);
}

/* 「试试问」这三个字。弱到接近注解 —— 它存在的理由是让下面那排 chip 有个归属，
   而不是再写一句「你可以问我什么」。 */
.realtime-chat-intro-lead {
    color: var(--text-muted);
}

/* 免责声明降级成底部一行脚注。它没有被删 —— 这是最该被看见的一句，只是原来
   夹在三段说明的中间，和「会引用线索」这种功能声明混在一起，看不出来是提醒。 */
.realtime-chat-disclaimer {
    margin: 12px 0 0 !important;
    font-size: 11.5px !important;
    color: var(--text-muted) !important;
    opacity: 0.85;
}

.realtime-chat-suggestions {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

/* 开场问题做成横排 chip，和回答下面的「接着问」同一套外观。
 *
 * 原来是三个占满整行宽的按钮，各带一个 26px 左边距的「问」字前缀。那一屏读起来像
 * 三个被禁用的输入框：满宽、有底色、左侧留出等输入框文字的位置。chip 的形状本身
 * 就说清了「这是个可点的短标签」，不需要再补一个字来提示。 */
.realtime-chat-suggestion {
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: none;
    color: var(--market-accent, #1576e8);
    font: inherit;
    font-size: 11.5px;
    line-height: 1.5;
    padding: 3px 9px;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, color 0.15s ease, background 0.15s ease;
}

.realtime-chat-suggestion:hover {
    border-color: var(--market-accent, #1576e8);
    background: color-mix(in srgb, var(--market-accent, #1576e8) 10%, transparent);
}

/* 接着问：跟着上一条回答动态生成的追问。
 *
 * 开场的问题也用同一套 chip 外观。同一个动作（点一下就问出去）就该有同一个样子，
 * 否则读者会以为它们功能不同。 */
.realtime-chat-followups {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 5px;
    margin-top: 10px;
    padding-top: 9px;
    border-top: 1px dashed var(--market-line);
}

.realtime-chat-followups-label {
    font-size: 11px;
    color: var(--text-muted);
    opacity: 0.85;
}

.realtime-chat-followup {
    padding: 3px 8px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: none;
    color: var(--market-accent, #1576e8);
    font: inherit;
    font-size: 11.5px;
    line-height: 1.5;
    text-align: left;
    cursor: pointer;
    transition: border-color 0.15s ease, background 0.15s ease;
}

.realtime-chat-followup:hover {
    border-color: var(--market-accent, #1576e8);
    background: color-mix(in srgb, var(--market-accent, #1576e8) 10%, transparent);
}

/* 输入区固定在窗口底部：内容区滚，输入框不动 —— 否则问完一轮要滚回去才能再问。 */
.realtime-chat-compose {
    display: flex;
    gap: 8px;
    align-items: flex-end;
    margin-top: 10px;
    padding-top: 10px;
    border-top: 1px solid var(--market-line);
}

.realtime-chat-input {
    flex: 1 1 auto;
    min-width: 0;
    max-height: 110px;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-soft, transparent);
    color: var(--text);
    font-family: inherit;
    font-size: 12.5px;
    line-height: 1.5;
    padding: 7px 10px;
    resize: none;
}

.realtime-chat-input:focus {
    outline: none;
    border-color: var(--market-brand);
}

.realtime-chat-send {
    flex: 0 0 auto;
    border: 1px solid var(--market-brand);
    border-radius: 8px;
    background: var(--market-brand);
    color: #fff;
    font-size: 12.5px;
    font-weight: 600;
    padding: 7px 14px;
    cursor: pointer;
}

.realtime-chat-send:disabled {
    opacity: 0.55;
    cursor: default;
}

/* 历史那一行。压得很低：它是复盘入口，不是这一栏的主功能。收起时只占一行，
   标题色用 muted，避免和「问点什么」的开场抢注意力。 */
.realtime-chat-history-bar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}

.realtime-chat-history-toggle,
.realtime-chat-new {
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 11.5px;
    padding: 3px 7px;
    cursor: pointer;
}

.realtime-chat-history-toggle:hover,
.realtime-chat-new:hover {
    border-color: var(--market-line);
    color: var(--text);
}

.realtime-chat-history-n {
    color: var(--market-amber);
    font-weight: 600;
}

/* 历史列表。限高并可滚：一列不设限的旧对话会把输入框顶到屏幕外，而输入框必须
   一直可见 —— 否则「翻旧记录」和「问新问题」变成了互斥的两件事。 */
.realtime-chat-history-list {
    max-height: 190px;
    margin-bottom: 10px;
    padding: 4px;
    overflow-y: auto;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel-soft, transparent);
}

.realtime-chat-history-row {
    display: flex;
    align-items: stretch;
    gap: 2px;
}

.realtime-chat-history-row.is-active {
    background: color-mix(in srgb, var(--market-amber) 10%, transparent);
    border-radius: 6px;
}

/* 标题单行省略：历史列表是按"我记得的那句话"找的，认得出开头比读得全重要，
   而两行标题会把 190px 的列表变成只放得下三条。 */
.realtime-chat-history-open {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text);
    font-family: inherit;
    font-size: 12px;
    text-align: left;
    padding: 5px 7px;
    cursor: pointer;
}

.realtime-chat-history-open:hover {
    background: color-mix(in srgb, var(--market-accent, #1576e8) 10%, transparent);
}

.realtime-chat-history-title {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.realtime-chat-history-meta {
    color: var(--text-muted);
    font-size: 10.5px;
}

/* 删除靠 hover 才显出存在感。它不可逆，但也不该和标题并排成两个一样重的东西 ——
   误点一次就没了，所以留一层 hover 才可点的余地。 */
.realtime-chat-history-delete {
    flex: 0 0 auto;
    display: flex;
    align-items: center;
    border: none;
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
    padding: 0 6px;
    cursor: pointer;
    opacity: 0.45;
}

.realtime-chat-history-delete:hover {
    opacity: 1;
    /* 删除是危险动作，按语义用涨红，不用主色 —— 蓝色在这里读起来像「确认」。 */
    color: var(--market-up);
}

/* 反馈行。贴着回答末尾，很轻：这是读完顺手说一句，不是阅读路径上的一环。
   默认几乎不可见（muted + 透明底），hover 回答时才提上来一点。 */
.realtime-chat-vote-row {
    display: flex;
    align-items: center;
    gap: 4px;
    margin-top: 8px;
    padding-top: 6px;
    border-top: 1px dashed var(--market-line);
    opacity: 0.55;
}

.realtime-chat-vote-row:hover {
    opacity: 1;
}

.realtime-chat-vote {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 24px;
    height: 24px;
    border: 1px solid transparent;
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
    cursor: pointer;
}

.realtime-chat-vote:hover {
    border-color: var(--market-line);
    color: var(--text);
}

.realtime-chat-vote.is-on {
    border-color: var(--market-brand);
    color: var(--market-brand);
}

.realtime-chat-vote-state {
    color: var(--text-muted);
    font-size: 10.5px;
}

/* 备注框。可选，所以窄而矮，不做成弹窗 —— 弹窗会挡住他正在评价的那段话。 */
.realtime-chat-note-form {
    display: flex;
    flex: 1 1 auto;
    gap: 4px;
    min-width: 0;
}

.realtime-chat-note-input {
    flex: 1 1 auto;
    min-width: 0;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel-soft, transparent);
    color: var(--text);
    font-family: inherit;
    font-size: 11.5px;
    padding: 4px 7px;
}

.realtime-chat-note-input:focus {
    outline: none;
    border-color: var(--market-amber);
}

.realtime-chat-note-send {
    flex: 0 0 auto;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: transparent;
    color: var(--text-muted);
    font-family: inherit;
    font-size: 11.5px;
    padding: 3px 8px;
    cursor: pointer;
}

.realtime-chat-note-send:hover {
    color: var(--text);
    border-color: var(--market-brand);
}

.realtime-analysis-warnings {
    margin: 0 0 10px;
    padding-left: 18px;
    font-size: 11.5px;
    line-height: 1.55;
    color: var(--market-amber);
}

.realtime-analysis-section {
    margin-bottom: 10px;
}

.realtime-analysis-section h5 {
    margin: 0 0 5px;
    font-size: 11.5px;
    font-weight: 600;
    color: var(--text-muted);
}

.realtime-analysis-section ul {
    margin: 0;
    padding-left: 18px;
    font-size: 12px;
    line-height: 1.6;
    color: var(--text);
}

.realtime-analysis-section li {
    margin-bottom: 4px;
    word-break: break-word;
}

.realtime-topic-chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
}

.realtime-topic-chip {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    border: 1px solid var(--market-line);
    border-radius: 999px;
    padding: 3px 9px;
    font-size: 11.5px;
    color: var(--text);
}

.realtime-topic-chip em {
    font-style: normal;
    font-size: 10.5px;
    color: var(--market-amber);
}

/*
 * 聊天面板：顶部群名 + 下方消息区，一个整体。
 *
 * 早先这里是三层（页面大标题、状态条、工具栏），把消息区往下推了约 200px，
 * 用户指出「消息窗口应该往上移」。现在只剩面板本身：群名给这一栏一个身份，
 * 状态信息收进群名右侧，不再各占一行。
 */
.realtime-chat {
    display: flex;
    flex-direction: column;
    min-width: 0;
    border: 1px solid var(--market-line);
    border-radius: 8px;
    background: var(--market-panel);
    overflow: hidden;
    /* 与右栏同高，说明见 .realtime-aside-window 上那段。 */
    height: var(--realtime-window-height);
    max-height: var(--realtime-window-height);
}

/*
 * 群名区。用稍深的底色把它和消息区区分开 —— 像群聊窗口的标题栏。
 *
 * 刻意不画下边框：底色已经足够把标题栏和消息区分开，再加一条实线就是两条分界
 * 叠在一起。用户指出那条线「不好看」，实测它在静默告警时还会变成琥珀色，比群名
 * 本身更抢眼。通道异常另有用处（状态字变成「连接中 / 通道未启动」并换色）。
 */
.realtime-chat-head {
    display: flex;
    align-items: center;
    gap: 10px;
    padding: 10px 14px;
    background: var(--market-panel-muted);
}

.realtime-chat-avatar {
    flex: 0 0 auto;
    width: 30px;
    height: 30px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border-radius: 8px;
    /* 蓝软底 + 蓝字，而不是实心琥珀：面板标识属于主色体系，实心色块会把
       标题栏的视觉重量抬到和正文一样高。 */
    background: var(--market-brand-soft);
    color: var(--market-brand);
    font-size: 14px;
    line-height: 1;
    user-select: none;
}

.realtime-chat-identity {
    min-width: 0;
    flex: 1 1 auto;
}

.realtime-chat-title {
    display: flex;
    align-items: center;
    min-width: 0;
    margin: 0;
    font-size: 14.5px;
    font-weight: 700;
    line-height: 1.3;
    color: var(--market-ink);
}

/* 群名是唯一会被截断的一段：容器再窄，VIP 徽章也必须留在群名后面。 */
.realtime-chat-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.realtime-chat-meta {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    margin-top: 2px;
    font-size: 11.5px;
    color: var(--text-muted);
}

/* 通道状态点：在线 / 连接中 / 未启动，用颜色和文字同时表达。 */
.realtime-chat-state {
    display: inline-flex;
    align-items: center;
    gap: 4px;
}
.realtime-chat-state::before {
    content: '';
    width: 6px;
    height: 6px;
    border-radius: 50%;
    background: currentColor;
}
.realtime-chat-state.is-live { color: var(--market-down); }
.realtime-chat-state.is-warning { color: var(--market-amber); }
.realtime-chat-state.is-error { color: var(--market-up); }

/* 会员身份牌：挂在群名后面，回答「这个群和我有什么关系」。
   用主色软底而不是实心琥珀 —— 它是身份标注，不是提醒。 */
.realtime-member-badge {
    display: inline-flex;
    align-items: center;
    flex: 0 0 auto;
    margin-left: 6px;
    padding: 1px 6px;
    border-radius: 4px;
    background: var(--market-brand-soft);
    color: var(--market-brand);
    font-size: 10.5px;
    font-weight: 700;
    line-height: 1.4;
    vertical-align: 1px;
}

/* 会员卖点：比状态字更轻，排在状态字后面，不抢群名的注意力。 */
.realtime-chat-value {
    color: var(--text-tertiary);
}

.realtime-chat-actions {
    display: flex;
    align-items: center;
    gap: 8px;
    flex: 0 0 auto;
}

/* 注意：不要用 .realtime-toggle —— style.css 已用它定义策略页的「实时解析」开关，
 * 重复定义会把那个开关的样式改掉。这里用独立的类名。 */
.realtime-autorefresh,
.realtime-push-toggle {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 11.5px;
    color: var(--text-muted);
    cursor: pointer;
    white-space: nowrap;
}

/* 推送开关打开时给一点视觉分量：它是这一栏里唯一会主动打断读者的设置，
 * 状态需要一眼可辨，而不是和「自动刷新」长得完全一样。 */
.realtime-push-toggle:has(input:checked) {
    color: var(--market-amber);
    font-weight: 600;
}

.realtime-refresh {
    padding: 4px 11px;
    border: 1px solid var(--market-line);
    border-radius: 7px;
    background: var(--market-panel);
    color: var(--market-ink);
    font-size: 11.5px;
    cursor: pointer;
    transition: border-color .15s ease, color .15s ease;
}
/* 刷新是「可交互」的动作，按颜色即语义归主色。 */
.realtime-refresh:hover { border-color: var(--market-brand); color: var(--market-brand); }

.realtime-warning {
    display: flex;
    flex-direction: column;
    gap: 4px;
    padding: 10px 14px;
    border: 1px solid var(--market-amber);
    border-radius: 8px;
    background: var(--market-amber-soft);
    font-size: 12px;
    color: var(--market-amber);
}

.realtime-state {
    padding: 40px 20px;
    text-align: center;
    font-size: 13px;
    color: var(--text-muted);
}
.realtime-state-error { color: var(--market-up); }

/*
 * 消息流容器。
 *
 * 固定高度 + 内部滚动，而不是让页面整体变长：聊天界面把「最新」锚在底部，
 * 页面整体滚动会让每次新消息把浏览器滚动位置顶走。
 *
 * 边框和圆角由外层面板负责（.realtime-chat），这里不再自己画一圈 —— 两层边框
 * 套在一起会有双线。
 *
 * 刻意不用 `scroll-behavior: smooth`。它会让每次程序化滚动都变成一段动画，
 * 于是「打开页面 / 来新消息」看起来就是画面从头飞到底部。聊天界面要的是即时
 * 定位，不是动画。
 */
.realtime-stream {
    display: flex;
    flex-direction: column;
    gap: 2px;
    /* 窗口（.realtime-chat）定高，消息区填满它剩下的高度并在其中滚动。
       上限和下限都归窗口管：这里原来自带 max-height: calc(100vh - 250px) 和
       min-height: 420px，那是窗口没定高时的权宜之计，而那个 250px 与右栏的
       140px 本来就不是同一个数 —— 两栏高度对不齐，一半的原因就在这里。 */
    flex: 1 1 auto;
    min-height: 0;
    overflow-y: auto;
    padding: 12px 14px;
    background: var(--market-panel);
    overflow-anchor: none;
}

/* 跨天分隔条：同一天内不重复出现，读起来才有连续感。 */
.realtime-day {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 14px 0 10px;
}
.realtime-day span {
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--market-panel-muted);
    font-size: 11px;
    color: var(--text-muted);
}

/*
 * 一条消息 = 一「电讯」。
 *
 * DOM 是固定顺序（时间戳在正文之后），所以用 grid + display:contents 把它
 * 重新排成「左时间列 + 右内容列」：时间戳提到第 1 列，正文落在第 2 列。
 * display:contents 只影响盒子的生成，不影响 querySelectorAll /
 * getBoundingClientRect —— JS 里那两处查找与定位照常工作。
 *
 * 时间戳是第一坐标轴：固定 64px、不换行、等宽数字。读者纵向扫一眼就能对齐
 * 整条时间线，这是快讯流与聊天气泡最根本的区别。
 *
 * 第 1 行只有右栏归档流会用到（放体裁徽章）；左栏的形态标注已删除，那一行
 * 没有内容时不占高度，正文自然顶到最上面。
 */
.realtime-message {
    display: grid;
    grid-template-columns: 64px minmax(0, 1fr);
    column-gap: 14px;
    padding: 12px 0;
    border-bottom: 1px solid var(--market-line-2);
}

/* 头像位取消：所有消息同一个投递方，每行都画一个「快」字圆片是纯噪音，
   正是聊天隐喻的残留。投递方已经在群名里交代过了。 */
.realtime-avatar {
    display: none;
}

/* 让 main 与 row 两层包装不生成盒子，好把孙节点直接摆进 article 的 grid 里。 */
.realtime-message-main {
    display: contents;
}

/* 右栏归档流里挂在正文上方的那一行，现在只放体裁徽章（卖方研报 / 专家纪要 /
 * 策略观点）。左栏不再有这一行：形态由气泡内容本身表达，不需要再写一遍。 */
.realtime-message-sender {
    grid-column: 2;
    grid-row: 1;
    font-size: 11px;
    color: var(--text-secondary);
    line-height: 1.4;
}

.realtime-message-row {
    display: contents;
}

/* 未读分界线：重新打开页面时标出「上次读到哪」，一眼可见而不必自己找。 */
.realtime-new-divider {
    display: flex;
    align-items: center;
    justify-content: center;
    margin: 12px 0 8px;
}
.realtime-new-divider span {
    padding: 2px 10px;
    border-radius: 999px;
    background: var(--market-amber-soft);
    color: var(--market-amber);
    font-size: 11px;
}

/* 「N 条新消息 ↓」：读者在翻历史时新消息只提示、不打断。
 * 按钮常驻在标题栏里，靠 hidden 属性切换显隐 —— 这样它的出现不会挤动旁边的
 * 「自动刷新」和「刷新」，也就不会在用户正要点击时把按钮挪走。 */
.realtime-jump {
    padding: 3px 9px;
    border: 1px solid var(--market-amber);
    border-radius: 999px;
    background: var(--market-amber-soft);
    color: var(--market-amber);
    font-size: 11.5px;
    white-space: nowrap;
    cursor: pointer;
}
.realtime-jump[hidden] { display: none; }
.realtime-jump:hover { background: var(--market-amber); color: #fff; }

/*
 * 正文块（沿用旧类名，但已经不再是「气泡」）。
 *
 * 去掉了底色、描边、圆角与内边距：内容直接落在白底上，靠字号与行距建立层级。
 * 一圈一圈的卡片框是「SaaS 后台」的语言，快讯流要的是报纸那种连续阅读感。
 *
 * min-width:0 + overflow-wrap 必须保留：正文来自第三方，可能包含超长 URL 或
 * 连续无空格的字符串，没有这两条会把内容列撑破、把整列布局推歪。
 */
.realtime-bubble {
    min-width: 0;
    grid-column: 2;
    grid-row: 2;
    /* 列宽已经由 grid 定死，正文只需要贴合它。 */
    max-width: 100%;
    padding: 0;
    overflow-wrap: anywhere;
    word-break: break-word;
}

.realtime-bubble-text {
    margin: 2px 0 0;
    font-size: 14px;
    line-height: 1.62;
    /* 正文用主文字色，而不是 --text-secondary。
       2026-10-12 用户反馈「字体是灰色的，不利于阅读」：这一页是会员每天要读的
       快讯正文，不是辅助说明。原来 #5a6270 在 14px/400 下笔画发虚，而标题是近
       黑色，两者落差一大，整段就读成「灰底注释」。同页的 AI 引用与分析正文
       （.realtime-citation-body / .realtime-analysis-section）本来就用 --text，
       这里跟着统一 —— 层级交给字号与时间戳去表达，不再靠把正文调灰来区分。 */
    color: var(--text);
    /* 保留原文里的换行：消息正文的分段是内容的一部分。 */
    white-space: pre-wrap;
}

.realtime-bubble-empty { color: var(--text-muted); font-style: italic; }

/* 从右侧搜索结果「在消息流里定位」跳过来时闪一下，否则用户看不出是哪一条。
   放在气泡规则旁边，因为它改的就是气泡外观。 */
.realtime-message-flash .realtime-bubble {
    animation: realtime-flash 1.6s ease;
}

@keyframes realtime-flash {
    0%, 100% { box-shadow: none; }
    20%, 60% { box-shadow: 0 0 0 2px var(--market-brand); }
}

/*
 * 图片消息的缩略图。
 *
 * 缩略图在后端已限制到 320px 以内，但显示尺寸要再小一些：新闻截图常常是竖版
 * （实测有 830x1468），按原尺寸渲染会把气泡拉得比一屏还高。max-height 与
 * max-width 同时给，两个方向都封顶。
 *
 * min-height 是为了在图片陆续加载时占住位置，否则消息列表会不断回流跳动。
 *
 * 这是 <button> 而不是 <a>：点击打开的是页内浮层，不是导航。用按钮还顺带拿到
 * 键盘可达性（Tab + Enter）。
 */
.realtime-bubble-image-link {
    display: block;
    position: relative;
    padding: 0;
    border: 0;
    line-height: 0;
    border-radius: 8px;
    overflow: hidden;
    background: none;
    cursor: zoom-in;
}

.realtime-bubble-image {
    display: block;
    max-width: 100%;
    max-height: 320px;
    width: auto;
    height: auto;
    min-height: 60px;
    min-width: 60px;
    border-radius: 8px;
    background: var(--market-panel);
    object-fit: contain;
}

/* 加载失败：藏起破图图标，露出下面的占位文字。 */
.realtime-image-fallback {
    display: none;
    font-size: 12.5px;
    color: var(--text-muted);
    font-style: italic;
    line-height: 1.6;
}
.realtime-bubble-image-link.realtime-image-failed .realtime-bubble-image { display: none; }
.realtime-bubble-image-link.realtime-image-failed .realtime-image-fallback { display: inline; }

.realtime-bubble-image-missing {
    margin: 0;
    font-size: 13px;
    color: var(--text-muted);
    font-style: italic;
}

/* 正文里的链接。正文来自第三方消息，所以链接是唯一允许的 HTML 结构，
 * 且协议已在 linkify 里白名单过滤（只认 http/https）。 */
.realtime-link {
    color: var(--market-brand);
    text-decoration: underline;
    text-underline-offset: 2px;
    /* 长 URL 必须能在内容列内换行，否则会把这一列撑破。 */
    overflow-wrap: anywhere;
    word-break: break-all;
}
.realtime-link:hover { text-decoration-thickness: 2px; }

/*
 * 图片放大浮层。
 *
 * 用 fixed 覆盖整个视口，所以它悬浮在**当前页面之上**，不跳走也不新开标签页 ——
 * 这是与 QQ / 飞书群里点图放大一致的行为。
 *
 * 浮层的定位上下文有个坑：`position: fixed` 的包含块不是视口，而是最近的有
 * transform / filter / backdrop-filter 的祖先。页面外层的 `.main` 带
 * `backdrop-filter`，所以浮层被挂到 document.body 下（见 JS 里的 ensureLightbox），
 * 否则 inset:0 只会盖住内容区。
 */
.realtime-lightbox {
    position: fixed;
    inset: 0;
    z-index: 2000;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 32px;
}
.realtime-lightbox[hidden] { display: none; }

.realtime-lightbox-backdrop {
    position: absolute;
    inset: 0;
    background: rgba(9, 14, 13, .82);
    cursor: zoom-out;
}

.realtime-lightbox-figure {
    position: relative;
    margin: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    max-width: 100%;
    max-height: 100%;
    overflow: auto;
}

/*
 * 图片按**宽度**铺满可用空间，高度不设视口上限。
 *
 * 早先这里有 `max-height: calc(100vh - 110px)`，把图片压进一屏。对长截图这是致命的：
 * 一张 661x6098 的图被压到 66px 宽，正文一个字都读不出来 —— 而点开它就是为了读。
 * 现在高度交给 figure 滚动（figure 已有 max-height:100% + overflow:auto），图片保持
 * 可读的宽度，读者往下滚就能看完整张图。
 */
.realtime-lightbox-image {
    display: block;
    max-width: 100%;
    width: auto;
    height: auto;
    border-radius: 8px;
    background: var(--market-panel);
    /* 浮层是深色背景，给图片一点亮边，避免深色截图糊在背景里。 */
    box-shadow: 0 18px 48px rgba(0, 0, 0, .45);
}

.realtime-lightbox-hint {
    font-size: 11.5px;
    color: rgba(255, 255, 255, .7);
}

.realtime-lightbox-close {
    position: absolute;
    top: 18px;
    right: 22px;
    width: 34px;
    height: 34px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    border: 0;
    border-radius: 50%;
    background: rgba(255, 255, 255, .16);
    color: #fff;
    font-size: 20px;
    line-height: 1;
    cursor: pointer;
}
.realtime-lightbox-close:hover { background: rgba(255, 255, 255, .28); }

/* 浮层打开时锁住背景滚动，否则滚轮会滚到后面的消息列。 */
body.realtime-lightbox-open { overflow: hidden; }

/*
 * 新消息推送卡片（右下角）。
 *
 * 和 QQ / 飞书一致：每条消息弹一张，不合并。财经快讯的价值在时效，把几条攒成
 * 「3 条新消息」会丢掉每条各自的时间点。
 *
 * 两个必须点：
 *
 *   * 容器挂在 body 上、position: fixed —— 读者可能正在别的栏目，而本页的
 *     root 在那种情况下是 display:none，挂在里面就一起被藏掉了。同时这也避开了
 *     `.main` 的 backdrop-filter 造成的定位上下文问题（浮层踩过同一个坑）。
 *   * z-index 高于浮层（2000）不行 —— 图片放大浮层是全屏模态，压住推送卡片是对的，
 *     所以这里用 1500：比页面内容高，比模态低。
 */
.realtime-push-stack {
    position: fixed;
    right: 20px;
    bottom: 20px;
    z-index: 1500;
    display: flex;
    flex-direction: column;
    /* 新的在下、旧的在上，视觉上像一叠纸从底部堆起来。 */
    gap: 10px;
    align-items: flex-end;
    pointer-events: none;
    max-width: min(360px, calc(100vw - 40px));
}

.realtime-push-card {
    pointer-events: auto;
    position: relative;
    width: 320px;
    max-width: 100%;
    padding: 12px 30px 12px 14px;
    border: 1px solid var(--market-line);
    border-left: 3px solid var(--market-amber);
    border-radius: 8px;
    background: var(--market-panel);
    box-shadow: 0 10px 28px rgba(15, 23, 42, .18);
    text-align: left;
    font: inherit;
    cursor: pointer;
    /* 入场动画：从右侧滑入并淡入。 */
    opacity: 0;
    transform: translateX(24px);
    transition: opacity .22s ease, transform .22s ease;
}

.realtime-push-card.is-in {
    opacity: 1;
    transform: translateX(0);
}

.realtime-push-card:hover {
    border-color: var(--market-amber);
}

.realtime-push-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 4px;
}

.realtime-push-title {
    font-size: 12px;
    font-weight: 700;
    color: var(--market-amber);
}

.realtime-push-time {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--text-muted);
}

.realtime-push-body {
    margin: 0;
    font-size: 12.5px;
    line-height: 1.5;
    color: var(--market-ink);
    /* 正文是第三方内容，可能含超长 URL；不换行会把卡片撑破。 */
    overflow-wrap: anywhere;
    word-break: break-word;
    /* 最多三行，超出省略 —— 卡片是提示，完整内容在消息页。 */
    display: -webkit-box;
    -webkit-line-clamp: 3;
    -webkit-box-orient: vertical;
    overflow: hidden;
}

.realtime-push-close {
    position: absolute;
    top: 6px;
    right: 8px;
    font-size: 15px;
    line-height: 1;
    color: var(--text-muted);
    cursor: pointer;
}
.realtime-push-close:hover { color: var(--market-ink); }

/* 系统偏好「减少动态效果」时不做位移动画，只淡入淡出。 */
@media (prefers-reduced-motion: reduce) {
    .realtime-push-card {
        transform: none;
        transition: opacity .15s ease;
    }
    .realtime-push-card.is-in { transform: none; }
}

/* 窄屏：卡片占满可用宽度，避免贴边留一条缝。 */
@media (max-width: 640px) {
    .realtime-push-stack {
        right: 10px;
        left: 10px;
        bottom: 10px;
        max-width: none;
        align-items: stretch;
    }
    .realtime-push-card { width: 100%; }
}

/*
 * 时间戳：第一坐标轴。
 *
 * 等宽字体 + tabular-nums 让「10:57 / 10:56 / 10:55」的冒号与数字严格对齐，
 * 纵向扫视时列是直的 —— 这是快讯流的可读性来源，也是它和金十/财联社那种
 * 「左侧一列时刻」最像的一点。固定宽度由 .realtime-message 的 grid 保证，
 * 这里只负责不换行。
 */
.realtime-message-time {
    grid-column: 1;
    grid-row: 1 / span 2;
    align-self: start;
    padding-top: 1px;
    font-family: "SF Mono", "JetBrains Mono", "Roboto Mono", ui-monospace, Consolas, monospace;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    line-height: 1.35;
    color: var(--text-secondary);
    white-space: nowrap;
}

/*
 * 时间戳落在未来（超过 FUTURE_ALERT_SECONDS）。
 *
 * 聊天视图显示的是绝对时刻，所以一个被时区误标的时间戳看起来和正常的一模一样 ——
 * 而它还会因为排序排到最底部，读起来就是「最新的一条」。用琥珀色把它标出来，
 * 让异常在消息流里可见，而不是只在 hover 的 title 里。
 */
.realtime-message-time-ahead {
    color: var(--market-amber);
    font-weight: 600;
}

/*
 * 左栏未读角标（微信式）。
 *
 * 定位成 absolute 挂在按钮右上角，所以按钮本身必须是定位上下文。角标不参与
 * 布局，因此它的出现与消失不会让导航栏抖动。
 */
.nav-btn {
    position: relative;
}

.nav-badge {
    position: absolute;
    top: 4px;
    right: 6px;
    /* 小号胶囊，而不是大角标：它是「有几条新的」的提示，不该在侧栏里
       比导航文字本身还抢眼。99+ 也放得下。 */
    min-width: 15px;
    height: 15px;
    padding: 0 4px;
    border-radius: 999px;
    background: var(--market-up, #dc2626);
    color: #fff;
    font-size: 10px;
    line-height: 15px;
    text-align: center;
    font-weight: 600;
    pointer-events: none;
}

@media (max-width: 980px) {
    /* 窄屏：右半边没有并排空间，消息列独占一行，检索窗口落到它下面。
       这里刻意不再 display:none —— 搜索和分类是这个页面的功能，不是装饰，
       藏起来等于在窄屏上删掉了功能。 */
    .realtime-shell { grid-template-columns: minmax(0, 1fr); }
    /* 窗口不再吸顶，也不再按视口限高：窄屏下它已经独占整宽，跟着页面滚就行。 */
    .realtime-aside-window { position: static; max-height: none; }
    .realtime-aside-body { overflow-y: visible; }
    /* 标题栏在窄屏会挤：群名一行，操作按钮换到下一行。 */
    .realtime-chat-head { flex-wrap: wrap; }
    .realtime-chat-actions { width: 100%; justify-content: flex-end; }
    .realtime-stream { max-height: none; min-height: 300px; }
    /* 窄屏时间列收窄一档：12px 等宽字下 44px 刚好容下 HH:MM，正文能多拿
       20px。规则写在基类的 grid 之上，不再用 flex-direction 去改方向 ——
       那是气泡时代的写法，对 grid 无效。 */
    .realtime-message { grid-template-columns: 44px minmax(0, 1fr); column-gap: 10px; }
    .realtime-lightbox { padding: 12px; }
    .realtime-lightbox-close { top: 10px; right: 12px; }
    /* 看板在窄屏：日历与热度并排，情绪占满下一行。顺序仍是日历 → 热度 →
       情绪，与宽屏一致，读者不需要重新学一遍。 */
    .realtime-dash {
        display: grid;
        grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
        gap: 0 18px;
    }
    .realtime-dash-block + .realtime-dash-block {
        border-top: none;
    }
    .realtime-dash-block:last-child {
        grid-column: 1 / -1;
        border-top: 1px solid var(--market-line-2);
    }
}

/* ========================================
   P4 暗色模式补充覆盖（2026-10-12）
   仅补三处此前遗漏的浅色底，避免触碰实时工作区与线索区的既有规则。
   ======================================== */

[data-theme="dark"] .market-event-theme-link.is-candidate {
    background: rgba(21, 118, 232, 0.16);
}

[data-theme="dark"] .market-event-ai-gaps li {
    background: rgba(255, 255, 255, 0.05);
}

[data-theme="dark"] .market-progress-track {
    background: linear-gradient(90deg,
        rgba(21, 118, 232, 0.28) 0 35%,
        rgba(180, 83, 9, 0.28) 35% 65%,
        rgba(224, 50, 60, 0.28) 65% 100%);
}

[data-theme="dark"] .market-context-axis-risk {
    background: linear-gradient(145deg, var(--market-panel), rgba(224, 50, 60, 0.14));
}
/* ========================================
   P4 暗色补丁 3（2026-10-12）
   本文件在 enhanced.css 之后加载，命令按钮与相似走势小图的暗色覆盖
   必须写在这里，否则会被本文件的浅色规则反压回去。
   ======================================== */

[data-theme="dark"] .market-command-btn {
    background: var(--bg-secondary);
    border-color: var(--border-color);
    color: var(--text-primary);
}

[data-theme="dark"] .market-command-btn-accent {
    background: var(--market-accent, #1576e8);
    border-color: var(--market-accent, #1576e8);
    color: #ffffff;
}

[data-theme="dark"] .market-command-btn-accent:hover,
[data-theme="dark"] .market-command-btn-accent:focus-visible {
    background: var(--market-accent-strong, #0b5fd0);
    border-color: var(--market-accent-strong, #0b5fd0);
}

[data-theme="dark"] .market-event-similar-spark {
    background: var(--bg-secondary);
}

/* ========================================
   P3 事件看板（2026-10-12）
   右栏默认视图：事件日历 / 题材热度 / 市场情绪。

   三块用 1px 分隔线分区，不做卡片套卡片、不加阴影 —— 外层已经是
   .realtime-aside-window 这一个窗口，再给每块套边框就会变回三张便签。
   圆角统一 ≤8px，与右栏其它控件一致。
   ======================================== */

.realtime-dash {
    display: flex;
    flex-direction: column;
    min-width: 0;
}

.realtime-dash-block {
    min-width: 0;
    padding: 12px 2px 14px;
}

.realtime-dash-block + .realtime-dash-block {
    border-top: 1px solid var(--market-line-2);
}

.realtime-dash-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 8px;
}

.realtime-dash-title {
    margin: 0;
    font-size: 12.5px;
    font-weight: 600;
    color: var(--text-strong, var(--text));
}

.realtime-dash-note {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--text-muted);
    white-space: nowrap;
}

/* 加载 / 失败 / 空态：三块各自一行说明，块与块之间仍然分隔。 */
.realtime-dash-state {
    padding: 6px 0 2px;
    font-size: 12px;
    line-height: 1.6;
    color: var(--text-muted);
}

.realtime-dash-state.is-error {
    color: var(--market-up);
}

/* --- 事件日历 --- */

.realtime-dash-cal {
    min-width: 0;
}

.realtime-dash-cal-month {
    padding: 0 2px 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--text-secondary);
}

.realtime-dash-cal-week,
.realtime-dash-cal-days {
    display: grid;
    grid-template-columns: repeat(7, minmax(0, 1fr));
    gap: 2px;
    text-align: center;
}

.realtime-dash-cal-week div {
    padding: 2px 0 5px;
    font-size: 11px;
    color: var(--text-muted);
}

.realtime-dash-day {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    height: 30px;
    border-radius: 6px;
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
}

.realtime-dash-day.is-other {
    color: var(--text-muted);
    opacity: 0.45;
}

/* 今天用主色实底：它回答的是「现在在哪一天」，不是涨跌。 */
.realtime-dash-day.is-today {
    background: var(--market-brand);
    color: #ffffff;
    font-weight: 600;
}

/* 有事件的那天在格子底部点一颗琥珀点，与未读提醒同色。 */
.realtime-dash-dot {
    position: absolute;
    bottom: 3px;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: var(--market-amber);
}

.realtime-dash-day.is-today .realtime-dash-dot {
    background: #ffffff;
}

/* --- 题材热度 --- */

.realtime-dash-hot {
    min-width: 0;
}

.realtime-dash-hot-row {
    display: grid;
    grid-template-columns: 74px minmax(0, 1fr) 46px;
    align-items: center;
    gap: 8px;
    min-width: 0;
    padding: 5px 0;
}

.realtime-dash-hot-name {
    overflow: hidden;
    font-size: 12.5px;
    color: var(--text);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.realtime-dash-hot-bar {
    display: block;
    height: 6px;
    overflow: hidden;
    border-radius: 3px;
    background: var(--market-line);
}

.realtime-dash-hot-bar i {
    display: block;
    height: 100%;
    border-radius: 3px;
    background: var(--market-brand);
}

.realtime-dash-hot-value {
    font-size: 12px;
    font-variant-numeric: tabular-nums;
    color: var(--text-secondary);
    text-align: right;
}

/* 第一名：条与数字用涨色。热度榜的第一名是「今天资金在往哪儿去」的指向。 */
.realtime-dash-hot-row.is-first .realtime-dash-hot-bar i {
    background: var(--market-up);
}

.realtime-dash-hot-row.is-first .realtime-dash-hot-value {
    color: var(--market-up);
    font-weight: 600;
}

/* --- 市场情绪 --- */

.realtime-dash-mood {
    display: grid;
    grid-template-columns: 88px minmax(0, 1fr);
    align-items: center;
    gap: 12px;
    min-width: 0;
}

.realtime-dash-ring {
    position: relative;
    width: 88px;
    height: 88px;
    border-radius: 50%;
    background: var(--market-line);
}

.realtime-dash-ring.is-empty {
    background: var(--market-line);
}

.realtime-dash-ring-inner {
    position: absolute;
    inset: 10px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    border-radius: 50%;
    /* 内孔必须用面板底色盖住 conic-gradient 的中心，否则环形会变成实心饼。 */
    background: var(--market-panel);
}

.realtime-dash-ring-inner b {
    font-size: 20px;
    font-variant-numeric: tabular-nums;
    line-height: 1.1;
    color: var(--text-strong, var(--text));
}

.realtime-dash-ring-inner span {
    margin-top: 2px;
    font-size: 10.5px;
    color: var(--text-muted);
}

.realtime-dash-mood-kv {
    min-width: 0;
}

.realtime-dash-mood-row {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    padding: 3px 0;
    font-size: 12px;
    color: var(--text-secondary);
}

.realtime-dash-mood-row b {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--text-strong, var(--text));
}

/* 涨跌成对出现时，红绿必须各落在自己的数字上：整行涂红会把「跌」
   也染成涨色，方向提示反而误导。 */
.realtime-dash-mood-value {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    white-space: nowrap;
}

/* 这两个选择器必须带上 .realtime-dash-mood-row b，否则会被上面那条
   `.realtime-dash-mood-row b`（0,1,1）以更高的特异性盖回中性文本色。 */
.realtime-dash-mood-row b.realtime-dash-mood-up {
    color: var(--market-up);
}

.realtime-dash-mood-row b.realtime-dash-mood-down {
    color: var(--market-down);
}

.realtime-dash-mood-sep {
    color: var(--text-muted);
}

/* 六因子拆解：综合分不是涨跌家数的直接换算，而是这六项归一化后的加权平均。
   做成紧凑的一列，让读者能对着每一格判断分数为什么低，而不是只看到一个 40。 */
.realtime-dash-factors {
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid var(--market-line-2);
}

.realtime-dash-factors-title {
    margin-bottom: 5px;
    font-size: 11px;
    color: var(--text-muted);
}

.realtime-dash-factor {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: 8px;
    min-width: 0;
    padding: 2px 0;
    font-size: 12px;
}

.realtime-dash-factor-name {
    min-width: 0;
    overflow: hidden;
    color: var(--text-secondary);
    text-overflow: ellipsis;
    white-space: nowrap;
}

.realtime-dash-factor-value {
    flex: 0 0 auto;
    font-variant-numeric: tabular-nums;
    font-weight: 600;
    color: var(--text-strong, var(--text));
}

.realtime-dash-factor-weight {
    margin-left: 5px;
    font-size: 10.5px;
    font-weight: 400;
    color: var(--text-muted);
}

/* =========================================================================
   当日复盘叙述时间轴
   =========================================================================
   轨道与上方情绪曲线同向（从左到右＝从旧到新），让两块共用一个日期直觉。
   节点是按钮而不是装饰：点它切换到那一天，下面才展开那一段记录。

   有叙述的节点画实心圆点，无叙述的画空心 —— 空心是刻意的，它是「那天没有
   记录」这一事实的可见形式，不做灰化隐藏，也不补一个替代读数。
   */
.market-narrative-section {
    padding: 13px 0 11px;
}

.market-narrative-title {
    min-width: 0;
}

.market-narrative-title h3 {
    margin: 0;
    font-size: 15px;
    line-height: 1.35;
}

.market-narrative-section .market-section-note {
    margin: 3px 0 0;
    font-size: 11.5px;
    line-height: 1.55;
    color: var(--text-muted);
}

.market-narrative-section .market-section-head {
    align-items: flex-start;
    margin-bottom: 6px;
}

.market-narrative-tools {
    display: flex;
    flex: 0 0 auto;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-end;
    gap: 7px 10px;
}

.market-emotion-window {
    display: inline-flex;
    overflow: hidden;
    border: 1px solid var(--market-line);
    border-radius: 6px;
    background: var(--market-panel);
}

.market-emotion-window button {
    min-width: 42px;
    height: 27px;
    padding: 0 8px;
    border: 0;
    border-right: 1px solid var(--market-line);
    background: transparent;
    color: var(--text-muted);
    font: inherit;
    font-size: 11px;
    line-height: 1;
    cursor: pointer;
}

.market-emotion-window button:last-child {
    border-right: 0;
}

.market-emotion-window button:hover,
.market-emotion-window button:focus-visible {
    background: var(--market-brand-soft);
    color: var(--market-brand);
    outline: none;
}

.market-emotion-window button.active {
    background: var(--market-brand);
    color: #fff;
    font-weight: 700;
}

.market-emotion-band-note {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 6px;
    margin: 0;
    color: var(--text-muted);
    font-size: 10.5px;
    line-height: 1.5;
}

.market-emotion-band-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: center;
    gap: 4px 16px;
    margin: 0 0 5px;
}

.market-emotion-band-row .market-emotion-summary {
    justify-self: end;
}

.market-emotion-band-note em {
    margin-left: 2px;
    color: var(--text-muted);
    font-style: normal;
}

.market-emotion-legend {
    display: inline-block;
    width: 13px;
    height: 7px;
    margin-left: 3px;
}

.market-emotion-legend.is-band {
    border: 1px solid rgba(21, 118, 232, .22);
    background: rgba(21, 118, 232, .10);
}

.market-emotion-legend.is-bound {
    height: 0;
    border-top: 1px dashed rgba(21, 118, 232, .55);
}

.market-emotion-legend.is-mean {
    height: 0;
    border-top: 1px solid rgba(100, 116, 139, .55);
}

.market-emotion-legend.is-temp {
    height: 0;
    border-top: 2px solid var(--market-brand);
}

.market-emotion-summary {
    display: block;
    margin: 0;
    border: 0;
    background: transparent;
}

.market-emotion-summary-line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 4px 16px;
    min-height: 20px;
    color: var(--text-muted);
    font-size: 11.5px;
    line-height: 1.55;
    font-variant-numeric: tabular-nums;
}

.market-emotion-summary-line b {
    color: var(--text-strong, var(--text));
    font-weight: 700;
}

.market-emotion-summary-line strong {
    color: var(--text-strong, var(--text));
    font-size: 13px;
}

.market-emotion-summary-line em {
    color: var(--text-secondary);
    font-style: normal;
    font-weight: 700;
}

.market-emotion-summary-line em.up {
    color: var(--market-up);
}

.market-emotion-summary-line em.down {
    color: var(--market-down);
}

.market-emotion-trail {
    min-width: 0;
    border: 1px solid var(--market-line);
    border-radius: 7px;
    background: var(--market-panel-muted);
}

.market-replay-grid {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: 12px;
    margin-top: 10px;
}

.market-replay-panel {
    min-width: 0;
}

.market-replay-panel-head {
    display: none;
}

.market-replay-grid.is-narrative-empty .market-replay-panel,
.market-replay-grid.has-narrative .market-replay-panel {
    padding: 8px 12px;
    border: 1px solid var(--market-line);
    border-radius: 7px;
    background: var(--market-panel-muted);
}

.market-replay-panel > .market-narrative-note {
    margin-top: 8px;
    padding-top: 8px;
}

.market-state-map-head h4 {
    margin: 0;
    color: var(--text-strong, var(--text));
    font-size: 13px;
    line-height: 1.4;
}

.market-state-map-head p {
    margin: 2px 0 0;
    color: var(--text-muted);
    font-size: 10.5px;
    line-height: 1.5;
}

.market-replay-grid .market-state-map {
    display: flex;
    min-width: 0;
    flex-direction: column;
    margin: 0;
    padding: 0;
    border-bottom: 0;
}

.market-replay-grid .market-state-map-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 8px;
    margin-bottom: 4px;
}

.market-replay-grid .market-state-map-head > div:first-child {
    min-width: 0;
}

.market-replay-grid .market-state-map-head h4 {
    margin: 0;
    white-space: nowrap;
}

.market-replay-grid #market-state-map-note {
    display: none;
}

.market-replay-grid .market-state-map-meta {
    display: flex;
    min-width: 0;
    flex: 1 1 auto;
    flex-wrap: nowrap;
    align-items: center;
    justify-content: flex-end;
    gap: 6px;
}

.market-replay-grid .market-state-map-meta .market-muted {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-size: 10.5px;
    line-height: 1.45;
}

.market-replay-grid .market-state-map-main {
    display: grid;
    min-width: 0;
    grid-template-columns: minmax(0, 1fr);
    align-items: start;
    gap: 14px;
    padding: 11px 13px;
}

.market-replay-grid .market-state-map-main {
    grid-template-columns: minmax(210px, .3fr) minmax(0, 1fr);
    grid-template-areas:
        "summary plot"
        "evidence evidence"
        "loss loss";
}

.market-replay-grid .market-state-summary {
    grid-area: summary;
}

.market-replay-grid .market-state-plot {
    grid-area: plot;
}

.market-replay-grid .market-state-evidence {
    grid-area: evidence;
}

.market-replay-grid .market-state-loss {
    grid-area: loss;
}

.market-replay-grid .market-state-summary {
    padding: 8px 14px 8px 4px;
    border-right: 1px solid var(--market-line);
    border-bottom: 0;
}

.market-replay-grid .market-state-summary strong {
    margin: 5px 0 3px;
    font-size: 22px;
}

.market-replay-grid .market-state-readings {
    grid-template-columns: minmax(0, 1fr);
    gap: 5px;
    margin-top: 9px;
}

.market-replay-grid .market-state-reading {
    grid-template-columns: minmax(48px, auto) minmax(0, 1fr);
}

.market-replay-grid .market-state-reading > small {
    display: block;
}

.market-replay-grid .market-state-reading-bar {
    margin-top: -3px;
}

.market-replay-grid .market-state-reading > b {
    font-size: 15px;
}

.market-replay-grid .market-state-plot {
    align-self: stretch;
    width: 100%;
    min-width: 0;
}

.market-replay-grid .market-state-canvas {
    height: 344px;
    min-height: 340px;
}

.market-replay-grid .market-state-loss-grid {
    grid-template-columns: repeat(4, minmax(0, 1fr));
}

.market-emotion-canvas {
    min-width: 0;
    max-width: 100%;
    overflow: hidden;
}

.market-emotion-plot {
    display: block;
    width: 100%;
    max-width: 100%;
    height: 156px;
}

.market-emotion-zone {
    pointer-events: none;
}

.market-emotion-zone.is-hot {
    fill: rgba(217, 119, 6, .055);
}

.market-emotion-zone.is-cold {
    fill: rgba(14, 116, 144, .055);
}

.market-emotion-threshold {
    stroke-width: 1;
    stroke-dasharray: 5 5;
    pointer-events: none;
}

.market-emotion-threshold.is-hot {
    stroke: rgba(180, 83, 9, .48);
}

.market-emotion-threshold.is-cold {
    stroke: rgba(14, 116, 144, .48);
}

.market-emotion-extreme-label {
    font-size: 10px;
    font-weight: 700;
    letter-spacing: 0;
    paint-order: stroke;
    stroke: var(--market-panel-muted);
    stroke-width: 3px;
    stroke-linejoin: round;
    pointer-events: none;
}

.market-emotion-extreme-label.is-hot {
    fill: #9a5a12;
}

.market-emotion-extreme-label.is-cold {
    fill: #176b80;
}

.market-emotion-grid {
    stroke: var(--market-line);
    stroke-width: 1;
    stroke-dasharray: 3 5;
}

.market-emotion-axis {
    fill: var(--text-muted);
    font-size: 10px;
    font-variant-numeric: tabular-nums;
}

.market-emotion-band {
    fill: rgba(21, 118, 232, .09);
    stroke: none;
}

.market-emotion-bound {
    fill: none;
    stroke: rgba(21, 118, 232, .42);
    stroke-width: 1;
    stroke-dasharray: 4 4;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.market-emotion-mean {
    fill: none;
    stroke: rgba(100, 116, 139, .55);
    stroke-width: 1;
    stroke-dasharray: 2 3;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.market-emotion-line {
    fill: none;
    stroke: var(--market-brand);
    stroke-width: 2;
    stroke-linecap: round;
    stroke-linejoin: round;
}

.market-emotion-node {
    cursor: pointer;
    outline: none;
}

.market-emotion-node.is-empty {
    cursor: default;
}

.market-emotion-dot {
    fill: var(--market-panel);
    stroke: var(--market-brand);
    stroke-width: 1.7;
    pointer-events: all;
    transition: fill .15s ease, stroke-width .15s ease;
}

.market-emotion-node.is-empty .market-emotion-dot {
    fill: var(--market-panel-muted);
    stroke: var(--text-muted);
    stroke-opacity: .7;
}

.market-emotion-node:hover .market-emotion-dot,
.market-emotion-node:focus-visible .market-emotion-dot {
    fill: var(--market-brand-soft);
    stroke-width: 3;
}

.market-emotion-node.is-empty:hover .market-emotion-dot,
.market-emotion-node.is-empty:focus-visible .market-emotion-dot {
    fill: var(--market-panel-muted);
    stroke: var(--text-muted);
}

.market-emotion-node:focus-visible .market-emotion-halo,
.market-emotion-node:focus-visible .market-emotion-dot {
    outline: none;
    stroke: var(--market-brand-strong);
}

.market-emotion-node.is-selected .market-emotion-dot {
    fill: var(--market-brand);
    stroke: var(--market-brand);
    stroke-width: 2.5;
}

.market-emotion-node.is-hot-extreme .market-emotion-dot {
    fill: #f4b35f;
    stroke: #a95f08;
}

.market-emotion-node.is-cold-extreme .market-emotion-dot {
    fill: #78bdcd;
    stroke: #14697d;
}

.market-emotion-node.is-hot-extreme.is-selected .market-emotion-dot,
.market-emotion-node.is-cold-extreme.is-selected .market-emotion-dot {
    fill: var(--market-brand);
    stroke: var(--market-brand);
}

.market-emotion-halo {
    fill: none;
    stroke: var(--market-brand);
    stroke-width: 1.5;
    opacity: .35;
    pointer-events: none;
}

.market-emotion-date {
    fill: var(--text-muted);
    font-size: 9px;
    font-variant-numeric: tabular-nums;
    pointer-events: none;
}

.market-emotion-date.is-selected {
    fill: var(--market-brand);
    font-weight: 700;
}

.market-emotion-empty {
    padding: 28px 16px;
    color: var(--text-muted);
    font-size: 12.5px;
    text-align: center;
}

.market-narrative-list {
    display: block;
    min-width: 0;
}

.market-narrative-card {
    display: grid;
    grid-template-columns: minmax(210px, .28fr) minmax(0, 1fr);
    align-items: stretch;
    overflow: hidden;
}

.market-narrative-detail {
    display: block;
    min-width: 0;
}

.market-narrative-focus {
    display: flex;
    flex-direction: column;
    justify-content: center;
    padding: 2px 16px 2px 2px;
    border-right: 1px solid var(--market-line);
}

.market-narrative-focus > span {
    display: block;
    margin-bottom: 4px;
    color: var(--market-brand);
    font-size: 10.5px;
    font-weight: 700;
}

.market-narrative-focus h4 {
    margin: 0;
    color: var(--text-strong, var(--text));
    font-size: 13.5px;
    font-weight: 700;
    line-height: 1.5;
    letter-spacing: 0;
}

.market-narrative-card-body {
    display: grid;
    min-width: 0;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0 18px;
    padding: 1px 12px;
}

.market-narrative-group {
    min-width: 0;
    padding: 2px 0;
}

.market-narrative-group.is-primary {
    border-bottom: 0;
}

.market-narrative-group-title {
    margin: 0 0 3px;
    color: var(--text-secondary);
    font-size: 10.5px;
    font-weight: 700;
    line-height: 1.45;
    letter-spacing: 0;
}

.market-narrative-bullets {
    margin: 0;
    padding: 0;
    list-style: none;
}

.market-narrative-bullet {
    /* 不再是「时段 | 正文 | 编号」三列表格。时段已经在句子里，正文就是
       一段话，行间只用一条细线分隔，让整块读起来像当天的一段记述。 */
    padding: 2px 0;
    border-top: 1px solid var(--market-line-2);
    font-size: 11.5px;
    line-height: 1.5;
}

.market-narrative-group.is-primary .market-narrative-bullet {
    font-size: 12px;
    font-weight: 600;
}

.market-narrative-bullet:first-child {
    border-top: 0;
}

.market-narrative-bullet-text {
    color: var(--text);
}

.market-narrative-ref {
    margin-left: 2px;
    font-size: 10px;
    line-height: 0;
}

.market-narrative-clue {
    padding: 0 1px;
    border: 0;
    border-bottom: 1px dotted var(--market-line-strong, var(--market-line));
    border-radius: 0;
    background: none;
    color: var(--text-muted);
    font: inherit;
    font-size: 10px;
    line-height: inherit;
    cursor: pointer;
}

.market-narrative-clue:hover,
.market-narrative-clue:focus-visible {
    border-bottom-color: #1576e8;
    color: #1576e8;
    outline: none;
}

.market-narrative-clue-text {
    /* 展开的原文与实时消息右栏同一套读法：左侧一条细线表明这是正文引的
       旁注，不是页面自己的另一段结论。 */
    margin: 8px 0 2px;
    padding: 2px 0 2px 11px;
    border-left: 1px solid var(--market-line);
    color: var(--text);
    font-size: 12.5px;
    line-height: 1.7;
}

.market-narrative-clue-content {
    position: relative;
}

.market-narrative-clue-text.is-collapsed .market-narrative-clue-content {
    max-height: calc(1.7em * 3);
    overflow: hidden;
}

.market-narrative-clue-text.is-collapsed .market-narrative-clue-content::after {
    content: '';
    position: absolute;
    right: 0;
    bottom: 0;
    left: 0;
    height: 1.7em;
    background: linear-gradient(to bottom, transparent, var(--market-panel));
    pointer-events: none;
}

.market-narrative-clue-text p {
    margin: 0;
}

/* 与实时消息的 AI 分析同一套读法：先看这件事是什么，再看它为什么重要。 */
.market-narrative-clue-logic {
    margin-top: 6px !important;
    color: var(--text-muted);
}

.market-narrative-clue-points {
    margin: 6px 0 0;
    padding-left: 18px;
    color: var(--text-muted);
}

.market-narrative-clue-more {
    margin-top: 8px;
    padding: 0;
    border: 0;
    background: none;
    color: #1576e8;
    font: inherit;
    font-size: 11px;
    cursor: pointer;
}

.market-narrative-clue-more:hover,
.market-narrative-clue-more:focus-visible {
    outline: none;
    text-decoration: underline;
}

.market-narrative-caliber {
    margin: 8px 0 0;
    padding-top: 6px;
    border-top: 1px solid var(--market-line);
    color: var(--text-muted);
    font-size: 11px;
    font-variant-numeric: tabular-nums;
}

.market-narrative-empty {
    margin: 0;
    padding: 10px 0;
    color: var(--text-muted);
    font-size: 12.5px;
}

.market-narrative-note {
    margin: 8px 0 0;
    font-size: 11.5px;
    line-height: 1.6;
}

@media (max-width: 1180px) {
    .market-replay-grid .market-state-map-head {
        display: flex;
    }
    .market-replay-panel > .market-narrative-note {
        margin-top: 8px;
        padding-top: 0;
    }
    .market-replay-grid .market-state-loss-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 860px) {
    .market-replay-grid .market-state-map-main {
        grid-template-columns: minmax(0, 1fr);
        grid-template-areas:
            "summary"
            "plot"
            "evidence"
            "loss";
    }
    .market-replay-grid .market-state-summary {
        padding: 0 0 8px;
        border-right: 0;
        border-bottom: 1px solid var(--market-line);
    }
    .market-narrative-card {
        grid-template-columns: minmax(0, 1fr);
    }
    .market-narrative-focus {
        padding: 8px 10px;
        border-right: 0;
        border-bottom: 1px solid var(--market-line);
    }
    .market-narrative-card-body {
        grid-template-columns: minmax(0, 1fr);
    }
    .market-replay-grid .market-state-canvas {
        height: 300px;
        min-height: 280px;
    }
}

@media (max-width: 760px) {
    .market-replay-grid .market-state-canvas {
        height: 240px;
        min-height: 220px;
    }
    .market-replay-grid .market-state-loss-grid {
        grid-template-columns: minmax(0, 1fr);
    }
}

@media (max-width: 720px) {
    .market-narrative-section {
        padding-top: 12px;
    }
    .market-narrative-section .market-section-head {
        display: grid;
        gap: 8px;
    }
    .market-narrative-tools {
        justify-content: space-between;
    }
    .market-emotion-window button {
        min-width: 39px;
    }
    .market-emotion-band-note {
        margin-bottom: 6px;
    }
    .market-emotion-band-row {
        grid-template-columns: minmax(0, 1fr);
        gap: 3px;
    }
    .market-emotion-band-row .market-emotion-summary {
        justify-self: stretch;
    }
    .market-emotion-summary-line {
        display: grid;
        grid-template-columns: minmax(0, 1fr) auto;
        gap: 2px 8px;
    }
    .market-emotion-summary-line span:last-child {
        grid-column: 1 / -1;
    }
    .market-narrative-focus h4 {
        font-size: 13.5px;
    }
    .market-narrative-card-body {
        padding: 2px 10px;
    }
    .market-narrative-group {
        padding: 2px 0;
        border-top: 0;
    }
    .market-narrative-group.is-primary {
        padding-bottom: 2px;
    }
    .market-narrative-group-title {
        margin-bottom: 3px;
    }
    .market-narrative-bullet {
        padding: 2px 0;
        font-size: 11.5px;
        line-height: 1.55;
    }
    .market-replay-grid .market-state-map-head {
        flex-wrap: wrap;
        align-items: flex-start;
    }
    .market-replay-grid .market-state-map-meta {
        flex: 1 0 100%;
        flex-wrap: wrap;
        justify-content: flex-start;
    }
    .market-replay-grid .market-state-map-meta .market-muted {
        flex: 1 1 auto;
        overflow: visible;
        white-space: normal;
    }
}

/* -------------------------------------------------------------------------
   Selected-day structure: evidence first, quadrant as supporting context.

   The old populated layout reserved a narrow left rail for two scores and then
   stretched the quadrant to 344px beside it. On a wide page that left a large
   empty column while the four transaction samples were pushed below both.
   Read the section in one order instead: conclusion, four sample cards, plot,
   then the three explanations.
   ------------------------------------------------------------------------- */
.market-replay-grid .market-state-map-main {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas:
        "verdict"
        "samples"
        "plot"
        "evidence";
    gap: 10px;
    padding: 10px 12px 12px;
}

.market-replay-grid .market-state-verdict {
    grid-area: verdict;
}

.market-replay-grid .market-state-samples {
    grid-area: samples;
}

.market-replay-grid .market-state-plot {
    grid-area: plot;
}

.market-replay-grid .market-state-evidence {
    grid-area: evidence;
}

.market-replay-grid .market-state-verdict {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(250px, .46fr);
    gap: 10px 18px;
    align-items: center;
    padding: 9px 11px;
    border-left: 3px solid var(--market-line-strong, var(--market-line));
    background: var(--market-panel-muted);
}

.market-state-verdict-copy {
    display: grid;
    min-width: 0;
    gap: 3px;
}

.market-state-verdict-copy > span {
    color: var(--text-muted);
    font-size: 10.5px;
    font-weight: 700;
}

.market-state-verdict-heading {
    display: flex;
    min-width: 0;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 3px 9px;
}

.market-state-verdict-heading strong {
    color: var(--text-primary);
    font-size: 17px;
    font-weight: 800;
    line-height: 1.35;
}

.market-state-verdict-heading em {
    color: var(--text-secondary);
    font-size: 10.5px;
    font-style: normal;
    font-weight: 700;
}

.market-state-verdict-copy p {
    margin: 0;
    color: var(--text-secondary);
    font-size: 11.5px;
    line-height: 1.55;
}

.market-replay-grid .market-state-readings {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    margin: 0;
}

.market-replay-grid .market-state-reading {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 1px 7px;
    padding: 6px 8px;
    border: 1px solid var(--market-line);
    background: var(--market-panel);
}

.market-replay-grid .market-state-reading > b {
    font-size: 17px;
}

.market-replay-grid .market-state-reading > small {
    font-size: 10px;
    line-height: 1.4;
}

.market-state-samples {
    min-width: 0;
    padding-top: 2px;
}

.market-state-samples-head {
    display: flex;
    align-items: flex-end;
    justify-content: space-between;
    gap: 12px;
    margin-bottom: 6px;
}

.market-state-samples-head h5 {
    margin: 0;
    color: var(--text-primary);
    font-size: 12px;
    font-weight: 750;
}

.market-state-samples-head p {
    margin: 1px 0 0;
    color: var(--text-muted);
    font-size: 10px;
    line-height: 1.45;
}

.market-state-sample-grid {
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 7px;
}

.market-state-sample {
    display: grid;
    min-width: 0;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 4px 8px;
    padding: 8px 9px;
    border: 1px solid var(--market-line);
    border-top: 3px solid var(--market-line-strong, var(--market-line));
    background: var(--market-panel-muted);
}

.market-state-sample.is-controlled {
    border-top-color: var(--market-up);
}

.market-state-sample.is-under_pressure {
    border-top-color: var(--market-amber);
}

.market-state-sample.is-deteriorating {
    border-top-color: var(--market-down);
}

.market-state-sample.is-unknown {
    border-top-style: dashed;
}

.market-state-sample-label {
    display: grid;
    min-width: 0;
    gap: 1px;
}

.market-state-sample-label b {
    color: var(--text-primary);
    font-size: 12px;
    font-weight: 750;
}

.market-state-sample-label span {
    display: -webkit-box;
    overflow: hidden;
    color: var(--text-muted);
    font-size: 9.5px;
    line-height: 1.4;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
}

.market-state-sample-return {
    display: grid;
    align-self: start;
    justify-items: end;
    gap: 0;
}

.market-state-sample-return strong {
    color: var(--text-primary);
    font-size: 16px;
    font-variant-numeric: tabular-nums;
    line-height: 1.2;
    white-space: nowrap;
}

.market-state-sample-return span {
    color: var(--text-muted);
    font-size: 8.5px;
    white-space: nowrap;
}

.market-state-sample-meta {
    display: flex;
    grid-column: 1 / -1;
    min-width: 0;
    flex-wrap: wrap;
    align-items: baseline;
    gap: 2px 7px;
    color: var(--text-muted);
    font-size: 9.5px;
}

.market-state-sample-meta em {
    color: var(--text-secondary);
    font-style: normal;
    font-weight: 700;
}

.market-state-sample.is-controlled .market-state-sample-meta em {
    color: var(--market-up);
}

.market-state-sample.is-under_pressure .market-state-sample-meta em {
    color: var(--market-amber);
}

.market-state-sample.is-deteriorating .market-state-sample-meta em {
    color: var(--market-down);
}

.market-state-sample-meta small {
    padding: 0 4px;
    border: 1px solid rgba(180, 83, 9, .3);
    color: var(--market-amber);
    font-size: 8.5px;
    line-height: 1.45;
    white-space: nowrap;
}

.market-state-sample-detail {
    display: flex;
    grid-column: 1 / -1;
    min-width: 0;
    flex-wrap: wrap;
    gap: 2px 7px;
    padding-top: 4px;
    border-top: 1px solid var(--market-line);
    color: var(--text-secondary);
    font-size: 9.5px;
    line-height: 1.4;
}

.market-state-sample-detail small.is-gap {
    color: var(--market-amber);
}

.market-replay-grid .market-state-plot {
    align-self: start;
    width: 100%;
    min-width: 0;
}

.market-replay-grid .market-state-canvas {
    height: 286px;
    min-height: 274px;
}

.market-replay-grid .market-state-zone {
    padding: 7px 9px;
    font-size: 9.5px;
    font-weight: 650;
    opacity: .82;
}

.market-replay-grid .market-state-evidence {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 7px;
    padding-top: 0;
}

.market-replay-grid .market-state-evidence-block {
    padding: 8px 9px;
}

.market-replay-grid .market-state-evidence-block h5 {
    margin-bottom: 4px;
    font-size: 10.5px;
}

.market-replay-grid .market-state-evidence-row {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 2px 7px;
}

.market-replay-grid .market-state-evidence-row > small {
    grid-column: 1 / -1;
    color: var(--text-muted);
    font-size: 9.5px;
    line-height: 1.4;
}

@media (max-width: 1180px) {
    .market-replay-grid .market-state-sample-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
    }
}

@media (max-width: 860px) {
    .market-replay-grid .market-state-verdict {
        grid-template-columns: minmax(0, 1fr);
    }
    .market-replay-grid .market-state-evidence {
        grid-template-columns: minmax(0, 1fr);
    }
    .market-replay-grid .market-state-canvas {
        height: 290px;
        min-height: 276px;
    }
    .market-state-marker {
        width: 24px;
        height: 24px;
    }
}

@media (max-width: 560px) {
    .market-replay-grid .market-state-map-main {
        padding: 9px;
    }
    .market-replay-grid .market-state-readings {
        grid-template-columns: minmax(0, 1fr);
    }
    .market-replay-grid .market-state-sample-grid {
        grid-template-columns: repeat(2, minmax(0, 1fr));
        gap: 5px;
    }
    .market-state-sample {
        padding: 7px;
    }
    .market-state-sample-label span {
        display: block;
        overflow: visible;
        white-space: normal;
        -webkit-line-clamp: unset;
    }
    .market-state-sample-return strong {
        font-size: 14px;
    }
    .market-state-samples-head p {
        font-size: 9.5px;
    }
    .market-replay-grid .market-state-canvas {
        height: 248px;
        min-height: 236px;
    }
    .market-state-marker {
        width: 20px;
        height: 20px;
        box-shadow:
            0 0 0 1.5px #1576e8,
            0 0 0 4px rgba(21, 118, 232, .11);
    }
    .market-state-trail-footer {
        display: grid;
        gap: 5px;
    }
    .market-state-trail-legend {
        justify-content: flex-start;
    }
}
