* {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
    background: #1a1a1a;
    color: #e0e0e0;
    padding: 20px;
}

.container {
    max-width: 1800px;
    margin: 0 auto;
}

header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding-bottom: 10px;
    border-bottom: 2px solid #333;
}

h1 {
    font-size: 24px;
    color: #fff;
}

.status {
    padding: 6px 12px;
    background: #2a2a2a;
    border-radius: 4px;
    font-size: 14px;
}

/* Warm-up progress pill in the header. Visible while either the live-feed
   subscribe or the rank pre-warm is still in progress; hidden once both are
   complete. Color matches the alert-chip "approaching" yellow so the
   "something's still loading" cue is consistent across the UI. */
.warmup-pill {
    padding: 6px 12px;
    background: rgba(181, 137, 0, 0.18);
    border: 1px solid #b58900;
    border-radius: 4px;
    color: #f0c000;
    font-size: 13px;
    font-weight: 500;
    margin-left: 8px;
}
.warmup-pill[hidden] { display: none; }

.controls {
    background: #2a2a2a;
    padding: 20px;
    border-radius: 8px;
    margin-bottom: 20px;
}

.control-group {
    display: flex;
    align-items: center;
    gap: 10px;
    margin-bottom: 15px;
    flex-wrap: wrap;
}

.control-group:last-child {
    margin-bottom: 0;
}

label {
    font-size: 14px;
    font-weight: 500;
}

input[type="file"] {
    padding: 6px;
    background: #1a1a1a;
    border: 1px solid #444;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 14px;
}

input[type="datetime-local"] {
    padding: 6px 10px;
    background: #1a1a1a;
    border: 1px solid #444;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 14px;
    min-width: 220px;
}

select {
    padding: 6px 10px;
    background: #1a1a1a;
    border: 1px solid #444;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 14px;
}

input[type="number"] {
    padding: 6px 10px;
    background: #1a1a1a;
    border: 1px solid #444;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 14px;
    width: 80px;
}

input[type="range"] {
    flex: 1;
    min-width: 200px;
    max-width: 300px;
}

button {
    padding: 8px 16px;
    background: #4a90e2;
    color: white;
    border: none;
    border-radius: 4px;
    cursor: pointer;
    font-size: 14px;
    font-weight: 500;
    transition: background 0.2s;
}

button:hover:not(:disabled) {
    background: #357abd;
}

button:disabled {
    background: #333;
    color: #666;
    cursor: not-allowed;
}

#playBtn {
    background: #4caf50;
}

#playBtn:hover:not(:disabled) {
    background: #45a049;
}

#pauseBtn {
    background: #ff9800;
}

#pauseBtn:hover:not(:disabled) {
    background: #e68900;
}

#resetBtn {
    background: #f44336;
}

#resetBtn:hover:not(:disabled) {
    background: #da190b;
}

/* Inline trade controls (sit at the right edge of the bottom info panel, row 2) */
.trade-controls-inline {
    display: flex;
    align-items: center;
    gap: 8px;
    margin-left: auto;
    flex-shrink: 0;
}

/* Inline playback controls (sit at the right edge of the bottom info panel, row 1,
   above the trade controls) */
.playback-controls-inline {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    flex-wrap: wrap;
}

.playback-controls-inline input[type="number"] {
    width: 70px;
}

.trade-controls-inline label,
.playback-controls-inline label {
    font-size: 12px;
    color: #888;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.buy-btn {
    background: #4caf50;
    font-weight: 600;
    min-width: 100px;
}

.buy-btn:hover:not(:disabled) {
    background: #45a049;
}

.sell-btn {
    background: #f44336;
    font-weight: 600;
    min-width: 100px;
}

.sell-btn:hover:not(:disabled) {
    background: #da190b;
}

.flatten-btn {
    background: #ffc107;
    color: #1a1a1a;
    font-weight: 700;
    min-width: 100px;
}

.flatten-btn:hover:not(:disabled) {
    background: #ffb300;
}

/* Stop buttons — same hue family as BUY/SELL but visually subordinate
   (lower min-width, transparent background, colored border) so the primary
   market BUY/SELL stay the dominant CTA. */
.buy-stop-btn,
.sell-stop-btn {
    background: transparent;
    font-weight: 600;
    min-width: 80px;
    padding: 6px 10px;
    border: 1px solid;
}
.buy-stop-btn { border-color: #4caf50; color: #4caf50; }
.sell-stop-btn { border-color: #f44336; color: #f44336; }
.buy-stop-btn:hover:not(:disabled) { background: rgba(76, 175, 80, 0.15); }
.sell-stop-btn:hover:not(:disabled) { background: rgba(244, 67, 54, 0.15); }

.trade-controls-inline #stopPriceInput { width: 80px; }

/* Pending stops list — full-width row that appears below the trade-controls
   row only when at least one stop is armed. */
.pending-stops-list {
    flex-basis: 100%;
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    padding: 6px 0 0 0;
    font-size: 12px;
}
.pending-stops-list .pending-stops-label {
    color: #888;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    align-self: center;
    margin-right: 4px;
}
.pending-stop-chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 3px 8px;
    border-radius: 12px;
    background: #2a2a2a;
    border: 1px solid;
    font-family: 'SF Mono', Consolas, Monaco, monospace;
}
.pending-stop-chip.buy { border-color: #4caf50; color: #b9f0bf; }
.pending-stop-chip.sell { border-color: #f44336; color: #f7c0bd; }
.pending-stop-chip .cancel-stop {
    background: transparent;
    border: none;
    color: #888;
    cursor: pointer;
    font-size: 14px;
    line-height: 1;
    padding: 0 2px;
}
.pending-stop-chip .cancel-stop:hover { color: #fff; }

.trade-log-btn {
    background: #666;
    font-weight: 500;
    min-width: 100px;
}

.trade-log-btn:hover {
    background: #777;
}

/* Mode toggle (Replay vs Live) */
.mode-row {
    margin-bottom: 10px;
    flex-wrap: wrap;
}

/* display: contents so the wrapper itself is transparent to .mode-row's
   flex layout — children behave as direct flex items. JS toggles to
   display: none in replay mode to hide the whole alert config block. */
.alerts-section {
    display: contents;
}

.alerts-divider {
    color: #444;
    margin: 0 12px;
    font-size: 16px;
}

.alerts-percent {
    color: #888;
    font-size: 12px;
    margin-left: -4px;
    margin-right: 4px;
}

#alertSaveBtn {
    background: #b58900;
    padding: 6px 12px;
    font-size: 12px;
}
#alertSaveBtn:hover:not(:disabled) {
    background: #cb9b00;
}

.alert-list {
    display: inline-flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-left: 6px;
    align-items: center;
}

.alert-chip {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    background: #1a1a1a;
    border: 1px solid #555;
    border-radius: 12px;
    padding: 2px 8px;
    font-size: 11px;
    color: #ccc;
    cursor: pointer;       /* clicking the chip switches the chart to its asset */
    transition: border-color 0.15s, color 0.15s, background 0.15s;
}
.alert-chip:hover { background: #222; border-color: #777; }

/* Approaching-threshold colors. Distance is in absolute percentage points
   from threshold (e.g., threshold=80, value=72 → 8pp away → yellow). */
.alert-chip-near-yellow {
    border-color: #b58900;
    color: #f0c000;
}
.alert-chip-near-red {
    border-color: #f44336;
    color: #ff8080;
}
/* Currently in alert state — value has crossed threshold. */
.alert-chip-fired {
    background: rgba(76, 175, 80, 0.18);
    border-color: #4caf50;
    color: #aaffaa;
}

.alert-chip-remove {
    cursor: pointer;
    color: #999;
    font-weight: bold;
    line-height: 1;
}
.alert-chip-remove:hover { color: #f44336; }

#alertClearBtn {
    background: #555;
    padding: 6px 12px;
    font-size: 12px;
}
#alertClearBtn:hover:not(:disabled) {
    background: #6a6a6a;
}

.alert-mute {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 11px;
    color: #aaa;
    cursor: pointer;
    user-select: none;
    margin-left: 4px;
}
.alert-mute input[type="checkbox"] { margin: 0; cursor: pointer; }

.playback-controls-inline #riskTargetInput,
.trade-controls-inline #riskTargetInput {
    width: 80px;
}

.alert-banner {
    background: #b58900;
    color: #fff;
    font-weight: 600;
    animation: alert-flash 0.6s ease-in-out 3;
}

@keyframes alert-flash {
    0%, 100% { background: #b58900; }
    50% { background: #f44336; }
}

/* Alert notification banner stack — fixed at the top of the viewport,
   stacks newest-on-top, each persists 30s before fading out. */
.alert-notifications {
    position: fixed;
    top: 12px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 10000;
    display: flex;
    flex-direction: column;
    gap: 6px;
    pointer-events: none;       /* dismiss button re-enables pointer-events */
    max-width: 92vw;
    width: max-content;
}

.alert-notification {
    pointer-events: auto;
    display: flex;
    align-items: center;
    gap: 14px;
    background: linear-gradient(90deg, #b58900, #d97706);
    color: #fff;
    padding: 10px 16px;
    border-radius: 6px;
    box-shadow: 0 6px 24px rgba(0, 0, 0, 0.55);
    font-size: 14px;
    font-weight: 500;
    animation: alert-slide-in 0.25s ease-out;
}

.alert-notification.dismissing {
    animation: alert-slide-out 0.25s ease-in forwards;
}

.alert-notification-text { flex: 1; }

.alert-notification-dismiss {
    cursor: pointer;
    color: rgba(255, 255, 255, 0.75);
    font-size: 18px;
    font-weight: bold;
    line-height: 1;
    user-select: none;
}
.alert-notification-dismiss:hover { color: #fff; }

@keyframes alert-slide-in {
    from { transform: translateY(-120%); opacity: 0; }
    to   { transform: translateY(0); opacity: 1; }
}
@keyframes alert-slide-out {
    from { transform: translateY(0); opacity: 1; }
    to   { transform: translateY(-120%); opacity: 0; }
}

.mode-btn {
    background: #333;
    color: #aaa;
    padding: 6px 16px;
    font-size: 13px;
    font-weight: 500;
    min-width: 80px;
}

.mode-btn:hover:not(:disabled) {
    background: #444;
    color: #fff;
}

.mode-btn.active {
    background: #4a90e2;
    color: #fff;
}

#connectBtn {
    background: #4caf50;
}
#connectBtn:hover:not(:disabled) {
    background: #45a049;
}

#disconnectBtn {
    background: #f44336;
}
#disconnectBtn:hover:not(:disabled) {
    background: #da190b;
}

.ghost-btn {
    background: #444;
    color: #ccc;
    padding: 6px 12px;
    font-size: 13px;
}
.ghost-btn:hover:not(:disabled) {
    background: #555;
    color: #fff;
}
.ghost-btn.active {
    background: #5091dc;
    color: #fff;
}
.ghost-btn.loading {
    background: #6a4ea3;
    color: #fff;
    animation: ghost-loading-pulse 1.2s ease-in-out infinite;
}
@keyframes ghost-loading-pulse {
    0%, 100% { opacity: 1; }
    50%      { opacity: 0.55; }
}

.ghost-config {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    margin-left: 6px;
    padding: 2px 6px;
    border-left: 1px solid #444;
}
.ghost-config[hidden] { display: none; }
.ghost-label {
    color: #888;
    font-size: 12px;
    margin-left: 4px;
}
.ghost-config select {
    font-size: 12px;
    padding: 2px 4px;
    background: #2a2a2a;
    color: #ddd;
    border: 1px solid #444;
    border-radius: 3px;
}

.tick-value-display {
    font-size: 12px;
    color: #aaa;
    background: #1a1a1a;
    padding: 4px 8px;
    border-radius: 4px;
    border: 1px solid #333;
    white-space: nowrap;
    min-width: 70px;
    text-align: center;
}

.dollar-risk-display {
    font-size: 12px;
    color: #e0c060;
    background: #1a1a1a;
    padding: 4px 8px;
    border-radius: 4px;
    border: 1px solid #333;
    white-space: nowrap;
    min-width: 140px;
    text-align: center;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.adv-price-display {
    font-size: 12px;
    color: #80c8e0;
    background: #1a1a1a;
    padding: 4px 8px;
    border-radius: 4px;
    border: 1px solid #333;
    white-space: nowrap;
    min-width: 90px;
    text-align: center;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.add-qty-display {
    font-size: 12px;
    color: #c080e0;
    background: #1a1a1a;
    padding: 4px 8px;
    border-radius: 4px;
    border: 1px solid #333;
    white-space: nowrap;
    min-width: 80px;
    text-align: center;
    font-weight: 500;
    font-variant-numeric: tabular-nums;
}

.dist-pct-input {
    width: 55px;
}

.risk-auto-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    font-size: 12px;
    color: #aaa;
    cursor: pointer;
    user-select: none;
}

.risk-auto-toggle input {
    margin: 0;
    cursor: pointer;
}

/* Speed Preset Inputs + Apply Buttons */
.speed-preset {
    display: inline-flex;
    align-items: stretch;
}

.playback-controls-inline .speed-preset-value {
    width: 56px;
    padding: 4px 6px;
    font-size: 12px;
    border-radius: 4px 0 0 4px;
    border-right: none;
    text-align: right;
}

.speed-preset-apply {
    background: #2a2a2a;
    padding: 4px 10px;
    font-size: 12px;
    min-width: 0;
    border-radius: 0 4px 4px 0;
    line-height: 1;
}

.speed-preset-apply:hover:not(:disabled) {
    background: #3a3a3a;
}

.progress-bar {
    position: relative;
    width: 300px;
    height: 24px;
    background: #1a1a1a;
    border: 1px solid #444;
    border-radius: 4px;
    overflow: hidden;
}

.progress-fill {
    height: 100%;
    background: linear-gradient(90deg, #4a90e2, #357abd);
    transition: width 0.3s;
    width: 0%;
}

#progressText {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    font-size: 12px;
    font-weight: 600;
    color: #fff;
    z-index: 1;
}

.info-panel {
    display: flex;
    /* gap: <row> <column>. Row-gap kept tight so wrapped rows (OHLC row →
       Tape/Trade-controls row → conditional pending-stops row) don't pile
       on extra vertical space. Column-gap stays generous for readability. */
    gap: 6px 30px;
    margin-top: 10px;
    padding-top: 8px;
    border-top: 1px solid #444;
    flex-wrap: wrap;
}

.trade-info-panel {
    background: #1f1f1f;
    padding: 15px;
    border-radius: 6px;
    border: 1px solid #3a3a3a;
    width: 100%;
    margin-top: 0;
}

.info-item {
    display: flex;
    flex-direction: column;
    gap: 2px;
}

.info-label {
    font-size: 11px;
    color: #888;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.info-item span:last-child {
    font-size: 16px;
    font-weight: 600;
    color: #fff;
}

.info-label abbr {
    color: #6aa3ff;
    text-decoration: none;
    cursor: help;
    margin-left: 2px;
    font-size: 10px;
    border-bottom: 1px dotted #6aa3ff;
}

.rank-low-n {
    color: #777 !important;
}

/* Yellow pill shown when the chart's data spans more than one contract
   (a roll in the loaded window, or the live prime→live contract seam). Needs
   its own [hidden] rule with !important: the bare `hidden` attribute is
   overridden by author display rules (same pattern as .weather-panel etc.). */
.contract-split-flag {
    align-self: center;
    background: #f5c518;
    color: #1a1a1a;
    font-size: 12px;
    font-weight: 600;
    padding: 3px 9px;
    border-radius: 4px;
    white-space: nowrap;
    cursor: help;
}
.contract-split-flag[hidden] { display: none !important; }

.info-item .rank-idx {
    font-size: 11px;
    color: #888;
    font-weight: 400;
}

/* Stop the bottom info-panel row from re-flowing on every tick. As barVolume,
   currentClose, tapePos, tickTime, prefetchStatus etc. update each second the
   text width changes — that ripples through the flex row and intermittently
   bumps the trade-controls block (Qty / $ Target / Risk / BUY / SELL / Trade
   Log) onto a new line. Two fixes combined:
     1. tabular-nums = all digit glyphs the same width (no jitter from "0" vs
        "1" sliding the layout).
     2. min-width on the live-changing readouts so digit-count growth doesn't
        widen the cell. */
.info-item span:last-child {
    font-variant-numeric: tabular-nums;
}
#currentTime, #currentOpen, #currentHigh, #currentLow, #currentClose,
#barVolume, #tickTime, #tapePos, #loadedSessions {
    display: inline-block;
    min-width: 80px;
}
#prefetchStatus {
    display: inline-block;
    min-width: 180px;
}

.position-text {
    font-weight: 700;
    font-size: 18px;
}

.total-pnl {
    font-weight: 700;
    font-size: 20px;
}

.chart-container {
    width: 100%;
    height: 600px;
    background: #2a2a2a;
    border-radius: 8px;
    padding: 10px;
}

/* Trade Log Modal */
.modal {
    display: none;
    position: fixed;
    z-index: 1000;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.7);
}

.modal-content {
    background-color: #2a2a2a;
    margin: 5% auto;
    padding: 0;
    border: 1px solid #444;
    border-radius: 8px;
    width: 90%;
    max-width: 1200px;
    max-height: 80vh;
    overflow: hidden;
    display: flex;
    flex-direction: column;
}

.modal-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 20px;
    border-bottom: 1px solid #444;
}

.modal-header h2 {
    margin: 0;
    color: #fff;
    font-size: 20px;
}

.close-modal {
    color: #888;
    font-size: 32px;
    font-weight: bold;
    cursor: pointer;
    line-height: 20px;
}

.close-modal:hover {
    color: #fff;
}

.modal-body {
    padding: 20px;
    overflow-y: auto;
    flex: 1;
}

.trade-log-table {
    width: 100%;
    border-collapse: collapse;
    font-size: 13px;
}

.trade-log-table th,
.trade-log-table td {
    padding: 10px;
    text-align: left;
    border-bottom: 1px solid #444;
}

.trade-log-table th {
    background: #1a1a1a;
    color: #888;
    font-weight: 600;
    text-transform: uppercase;
    font-size: 11px;
    letter-spacing: 0.5px;
    position: sticky;
    top: 0;
}

.trade-log-table td {
    color: #e0e0e0;
}

.trade-log-table tr:hover {
    background: #333;
}

.trade-positive {
    color: #4caf50;
    font-weight: 600;
}

.trade-negative {
    color: #f44336;
    font-weight: 600;
}

.trade-stats {
    margin-top: 20px;
    padding: 20px;
    background: #1a1a1a;
    border-radius: 6px;
    display: flex;
    gap: 40px;
    flex-wrap: wrap;
}

.stat-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.stat-label {
    font-size: 11px;
    color: #888;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.stat-value {
    font-size: 18px;
    font-weight: 700;
    color: #fff;
}

.empty-log {
    text-align: center;
    padding: 40px;
    color: #888;
    font-size: 14px;
}

/* Trade Log: metrics, equity chart, actions */
.trade-metrics { margin-bottom: 16px; }

.metrics-section-title {
    font-size: 11px;
    color: #888;
    text-transform: uppercase;
    letter-spacing: 0.5px;
    font-weight: 600;
    margin: 14px 0 8px;
}
.metrics-section-title:first-child { margin-top: 0; }

.metrics-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
    gap: 10px 24px;
    background: #1a1a1a;
    border-radius: 6px;
    padding: 14px 18px;
}

.metric-item { display: flex; flex-direction: column; gap: 3px; }

.metric-label {
    font-size: 10px;
    color: #888;
    text-transform: uppercase;
    letter-spacing: 0.5px;
}

.metric-value {
    font-size: 16px;
    font-weight: 700;
    color: #fff;
}

.equity-details {
    margin: 16px 0;
    border: 1px solid #444;
    border-radius: 6px;
    background: #1a1a1a;
}
.equity-details > summary {
    cursor: pointer;
    padding: 10px 14px;
    user-select: none;
    font-size: 13px;
    font-weight: 600;
    color: #e0e0e0;
}
.equity-details > summary:hover { color: #fff; }
.equity-details[open] > summary { border-bottom: 1px solid #333; }

.equity-chart {
    width: 100%;
    height: 240px;
    padding: 6px;
    box-sizing: border-box;
}

.trade-log-actions {
    display: flex;
    gap: 10px;
    margin: 12px 0;
}
.trade-log-actions button {
    padding: 7px 14px;
    background: #2a2a2a;
    border: 1px solid #444;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 13px;
    cursor: pointer;
}
.trade-log-actions button:hover:not(:disabled) { background: #3a3a3a; }
.trade-log-actions button:disabled { opacity: 0.5; cursor: not-allowed; }

.bid-color {
    color: #4caf50 !important;
}

.ask-color {
    color: #f44336 !important;
}

.info-item-wide {
    min-width: 280px;
}

.info-item-wide span:last-child {
    font-size: 13px;
    line-height: 1.4;
}

/* ---------- Weather panel (docs/weather-data-spec.md §8) ---------- */

.weather-toggle-btn {
    margin-left: 8px;
    padding: 6px 12px;
    background: #2a2a2a;
    border: 1px solid #444;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 13px;
    cursor: pointer;
}
.weather-toggle-btn:hover { background: #3a3a3a; }
.weather-toggle-btn.active {
    background: #1f4d6b;
    border-color: #4a90c2;
    color: #fff;
}

/* Fixed sidebar that overlays the left side of the viewport. The user
   can hover bars without the panel re-flowing the chart. */
.weather-panel {
    position: fixed;
    left: 12px;
    /* Bottom-anchored: pin 10px from the screen bottom (half the former
       20px design margin → panel sits lower, no variable float-up gap when
       content is short). Grows upward; max-height keeps the top edge no
       higher than the former y=220 so it never overlaps the controls. */
    bottom: 10px;
    width: 480px;
    max-height: calc(100vh - 230px);
    overflow-y: auto;
    background: #1f1f1f;
    border: 1px solid #444;
    border-radius: 6px;
    padding: 10px 12px;
    font-family: 'Consolas', 'Menlo', 'Courier New', monospace;
    font-size: 12px;
    color: #d8d8d8;
    box-shadow: 0 4px 16px rgba(0,0,0,0.5);
    z-index: 50;
}
.weather-panel[hidden] { display: none !important; }

.weather-header {
    font-weight: bold;
    color: #fff;
    border-bottom: 1px solid #444;
    padding-bottom: 6px;
    margin-bottom: 8px;
    letter-spacing: 0.5px;
}

.weather-loading, .weather-error, .weather-empty, .weather-note {
    padding: 8px 4px;
    color: #999;
    font-size: 11px;
}
.weather-error  { color: #e57373; }
.weather-empty  { color: #c0a060; }
.weather-note   {
    margin-top: 8px;
    border-top: 1px dashed #333;
    padding-top: 6px;
    line-height: 1.4;
}

.weather-table {
    width: 100%;
    border-collapse: collapse;
    margin: 4px 0 10px;
    table-layout: fixed;
}
.weather-table th, .weather-table td {
    padding: 3px 4px;
    text-align: right;
    border-bottom: 1px dotted #333;
    font-variant-numeric: tabular-nums;
}
.weather-table thead th {
    color: #888;
    font-weight: normal;
    font-size: 11px;
    text-align: right;
}
.weather-table th.rname {
    text-align: left;
    color: #aaa;
    font-weight: normal;
    width: 28%;
}
.weather-table .ddc {
    width: 12%;
    color: #d0d0d0;
}

/* Heating/cooling tint on the dominant-DD cell. */
.weather-table .dd-h { color: #6cb6ff; }   /* blue = HDD */
.weather-table .dd-c { color: #f0a04a; }   /* orange = CDD */

/* Revision direction tint. Positive = colder/heavier load → blue, negative → red. */
.weather-rev .rev-up { color: #6cb6ff; }
.weather-rev .rev-dn { color: #ff8a80; }

/* Z-score badges. */
.weather-z .z-high     { color: #f1c40f; font-weight: bold; }
.weather-z .z-extreme  { color: #ff6464; font-weight: bold; }

/* Basin freeze color thresholds (spec §4.7). */
.weather-basins .frz-mod  { color: #f1c40f; }   /* yellow: 20-32°F */
.weather-basins .frz-high { color: #ff6464; font-weight: bold; }   /* red: <20°F */

.weather-ao {
    margin-top: 6px;
    padding: 6px 4px;
    border-top: 1px dotted #333;
}
.weather-ao-row {
    display: flex;
    gap: 12px;
    align-items: center;
    font-size: 12px;
}
.weather-ao-row .rname {
    color: #aaa;
    min-width: 28%;
}

/* ---------- Rank Compare panel (replay only) ---------- */
.rank-compare-btn {
    margin-left: 6px;
    padding: 6px 12px;
    background: #2a2a2a;
    border: 1px solid #444;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 13px;
    cursor: pointer;
}
.rank-compare-btn:hover { background: #3a3a3a; }
.rank-compare-btn.active {
    background: #1f4d6b;
    border-color: #4a90c2;
    color: #fff;
}
.rank-compare-btn:disabled {
    opacity: 0.45;
    cursor: not-allowed;
}

/* Anchored to the bottom of the viewport (vs the weather panel which is
   anchored to the top) — keeps the panel near the action and gives a
   stable bottom gap regardless of viewport height or row count. */
.rank-compare-panel {
    position: fixed;
    left: 12px;
    bottom: 60px;
    width: 320px;
    max-height: calc(100vh - 240px);
    overflow-y: auto;
    background: #1f1f1f;
    border: 1px solid #444;
    border-radius: 6px;
    padding: 10px 12px;
    font-family: 'Consolas', 'Menlo', 'Courier New', monospace;
    font-size: 12px;
    color: #d0d0d0;
    z-index: 50;
}
.rank-compare-panel[hidden] { display: none !important; }

/* If weather is also visible, the rank panel sits to its right so they
   don't overlap. The selector targets siblings: weather not-hidden,
   then any following rank-compare panel. */
.weather-panel:not([hidden]) ~ .rank-compare-panel {
    left: 504px;   /* weather is 480px wide + 12px left + 12px gap */
}

.rank-compare-header {
    font-weight: bold;
    color: #fff;
    border-bottom: 1px solid #444;
    padding-bottom: 6px;
    margin-bottom: 6px;
    letter-spacing: 0.5px;
}
.rank-compare-sub {
    color: #888;
    font-size: 11px;
    margin: -2px 0 6px;
}

/* Live progress line: counts of ranks/bars resolved so the user can see
   the panel is still working during cold-cache builds. */
.rank-compare-status {
    color: #f1c40f;
    font-size: 11px;
    margin: 0 0 4px;
    font-variant-numeric: tabular-nums;
}

.rank-compare-table {
    width: 100%;
    border-collapse: collapse;
    table-layout: fixed;
}
.rank-compare-table th, .rank-compare-table td {
    padding: 3px 4px;
    border-bottom: 1px dotted #2a2a2a;
    font-variant-numeric: tabular-nums;
    font-size: 12px;
    text-align: right;
}
.rank-compare-table thead th {
    color: #888;
    font-weight: normal;
    font-size: 11px;
}
.rank-compare-table .col-asset { width: 36px; text-align: left; color: #aaa; }
.rank-compare-table .col-vol   { width: 78px; }
.rank-compare-table .col-range { width: 78px; }
.rank-compare-table .col-oc    { width: auto; }

.rank-compare-table .rank-val { color: #d0d0d0; }
.rank-compare-table .rank-val.rank-hot { color: #f0625b; font-weight: bold; }
.rank-compare-table .rank-idx { color: #777; font-size: 10px; margin-left: 3px; }
.rank-compare-table .rank-low-n { color: #777; }     /* dim if n < threshold */
.rank-compare-table .rank-missing { color: #555; }
.rank-compare-table .rank-loading { color: #666; font-style: italic; }
.rank-compare-table .rank-err { color: #ff8a80; }

.rank-compare-table .oc-pos { color: #4caf50; }
.rank-compare-table .oc-neg { color: #f0625b; }
.rank-compare-table .oc-zero { color: #888; }

.rank-compare-empty {
    color: #999;
    font-size: 11px;
    padding: 8px 4px;
}

/* ---------------- Trend Status panel ---------------- */
.trend-status-btn {
    margin-left: 6px;
    padding: 6px 12px;
    background: #2a2a2a;
    border: 1px solid #444;
    border-radius: 4px;
    color: #e0e0e0;
    font-size: 13px;
    cursor: pointer;
}
.trend-status-btn:hover { background: #3a3a3a; }
.trend-status-btn.active {
    background: #1f4d6b;
    border-color: #4a90c2;
    color: #fff;
}

/* Bottom-right corner: deliberately on the opposite side from the
   bottom-left rank-compare panel so the two never overlap regardless of
   which combination is toggled on. */
.trend-status-panel {
    position: fixed;
    right: 12px;
    bottom: 60px;
    width: 300px;
    background: #1f1f1f;
    border: 1px solid #444;
    border-radius: 6px;
    padding: 10px 12px;
    font-family: 'Consolas', 'Menlo', 'Courier New', monospace;
    font-size: 12px;
    color: #d0d0d0;
    z-index: 50;
}
.trend-status-panel[hidden] { display: none !important; }

.trend-status-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-weight: bold;
    color: #fff;
    border-bottom: 1px solid #444;
    padding-bottom: 6px;
    margin-bottom: 6px;
    letter-spacing: 0.5px;
}
.ts-config { display: flex; gap: 6px; }
.ts-cfg-label {
    color: #888;
    font-weight: normal;
    font-size: 10px;
    display: flex;
    align-items: center;
    gap: 2px;
}
.ts-window-input {
    width: 34px;
    padding: 1px 2px;
    background: #2a2a2a;
    border: 1px solid #444;
    border-radius: 3px;
    color: #e0e0e0;
    font-size: 11px;
    font-family: inherit;
}

.trend-status-legend {
    display: flex;
    align-items: center;
    gap: 4px;
    color: #888;
    font-size: 10px;
    margin-bottom: 8px;
}
.trend-status-legend .ts-block { margin-right: 1px; }

.trend-status-row {
    display: flex;
    align-items: center;
    gap: 8px;
    margin: 5px 0;
}
.ts-label {
    width: 52px;
    flex: none;
    color: #aaa;
    font-size: 11px;
}
.ts-strip {
    flex: 1 1 auto;
    display: flex;
    flex-wrap: wrap;
    gap: 1px;
    min-width: 0;
}
.ts-block {
    display: inline-block;
    width: 4px;
    height: 14px;
    border-radius: 1px;
    box-sizing: border-box;
}
.ts-greenL3 { background: #26a69a; }
.ts-redL3   { background: #ef5350; }
.ts-neutral { background: #f0f0f0; border: 1px solid #999; }

.ts-counts {
    flex: none;
    display: flex;
    gap: 6px;
    font-variant-numeric: tabular-nums;
    font-size: 11px;
}
.ts-counts small { color: #777; font-size: 9px; }
.ts-c-g { color: #26a69a; }
.ts-c-r { color: #ef5350; }
.ts-c-w { color: #ccc; }

.trend-status-empty {
    color: #999;
    font-size: 11px;
    padding: 8px 4px;
}