/*
 * Styles for live.html (the live tape and the 24-hour replay). The colour tokens, the dark-mode
 * block, the header, chips and ghost buttons are mirrored from stocks.css and graph.css so the
 * three pages look like one site; the tape, the counters, the timeline and the eight venue colour
 * slots are new here. Written mobile-first: the base rules are the 300–400 px layout (tape rows as
 * cards, one counter per line) and the wider layouts are added at min-width breakpoints.
 */

:root {
    color-scheme: light;
    --page-bg: #ffffff;
    --page-text: #111827;
    --panel-border: #d1d5db;
    --muted-text: #6b7280;
    --control-bg: #ffffff;
    --control-text: #111827;
    --control-border: #9ca3af;
    --link-color: #2563eb;
    --card-bg: #ffffff;
    --sunken-bg: #f9fafb;
    --header-bg: #e5e7eb;
    --header-text: #111827;
    --accent: #8b5cf6;
    --sev-caution: #b45309;
    --sev-critical: #b91c1c;
    --up: #15803d;
    --down: #b91c1c;
    --flash-bg: #fef3c7;
    /* Eight venue slots, shared by the tape dots, the pool chips, the stacked bars and the
       legend, so one venue is one colour everywhere on the page. The eighth is deliberately
       neutral: it is also where every venue past the eighth lands. */
    --venue-a: #0e7490;
    --venue-b: #7c3aed;
    --venue-c: #b45309;
    --venue-d: #15803d;
    --venue-e: #be185d;
    --venue-f: #4338ca;
    --venue-g: #0369a1;
    --venue-h: #6b7280;
}

@media (prefers-color-scheme: dark) {
    :root {
        color-scheme: dark;
        --page-bg: #0f1117;
        --page-text: #f9fafb;
        --panel-border: #374151;
        --muted-text: #9ca3af;
        --control-bg: #111827;
        --control-text: #f9fafb;
        --control-border: #4b5563;
        --link-color: #93c5fd;
        --card-bg: #151922;
        --sunken-bg: #1f2937;
        --header-bg: #1f2937;
        --header-text: #f9fafb;
        --sev-caution: #fbbf24;
        --sev-critical: #f87171;
        --up: #4ade80;
        --down: #f87171;
        --flash-bg: #3f3410;
        --venue-a: #22d3ee;
        --venue-b: #a78bfa;
        --venue-c: #fbbf24;
        --venue-d: #4ade80;
        --venue-e: #f472b6;
        --venue-f: #818cf8;
        --venue-g: #60a5fa;
        --venue-h: #9ca3af;
    }
}

* {
    box-sizing: border-box;
}

body {
    background: var(--page-bg);
    color: var(--page-text);
    font-family: system-ui, sans-serif;
    margin: 12px;
    overflow-x: hidden;
}

a {
    color: var(--link-color);
}

h1 {
    margin: 0;
    font-size: 1.3rem;
}

h2 {
    font-size: 1.15rem;
    margin: 0 0 6px;
}

section {
    margin: 0 0 28px;
}

/* --- header ----------------------------------------------------------- */

.page-header {
    display: flex;
    align-items: center;
    gap: 12px;
    flex-wrap: wrap;
    margin: 0 0 12px;
}

.brand svg {
    width: 44px;
    height: 44px;
    display: block;
}

.back-link {
    font-size: 0.9rem;
    white-space: nowrap;
}

/* The first nav link pushes the group to the right once there is room for it. */
.back-link:first-of-type {
    margin-left: auto;
}

a.tab-button {
    text-decoration: none;
}

.method-note {
    margin: 0 0 8px;
    max-width: 78ch;
    line-height: 1.55;
}

.data-line {
    margin: 0 0 12px;
    font-size: 0.88rem;
    color: var(--muted-text);
}

.status {
    margin: 0 0 16px;
    font-size: 0.88rem;
    color: var(--muted-text);
}

.status-error {
    color: var(--sev-critical);
    font-weight: 600;
}

.sample-banner {
    margin: 0 0 16px;
    padding: 8px 12px;
    border: 1px solid var(--sev-caution);
    border-radius: 8px;
    background: var(--sunken-bg);
    font-size: 0.88rem;
}

.section-note {
    margin: 0 0 12px;
    font-size: 0.88rem;
    color: var(--muted-text);
    max-width: 82ch;
    line-height: 1.5;
}

.collection-line {
    margin: 0 0 10px;
    font-size: 0.92rem;
    font-weight: 600;
}

/* --- venue colour slots ----------------------------------------------- */

.venue-0 { --venue-color: var(--venue-a); }
.venue-1 { --venue-color: var(--venue-b); }
.venue-2 { --venue-color: var(--venue-c); }
.venue-3 { --venue-color: var(--venue-d); }
.venue-4 { --venue-color: var(--venue-e); }
.venue-5 { --venue-color: var(--venue-f); }
.venue-6 { --venue-color: var(--venue-g); }
.venue-7 { --venue-color: var(--venue-h); }

.venue-fill-0 { --venue-color: var(--venue-a); }
.venue-fill-1 { --venue-color: var(--venue-b); }
.venue-fill-2 { --venue-color: var(--venue-c); }
.venue-fill-3 { --venue-color: var(--venue-d); }
.venue-fill-4 { --venue-color: var(--venue-e); }
.venue-fill-5 { --venue-color: var(--venue-f); }
.venue-fill-6 { --venue-color: var(--venue-g); }
.venue-fill-7 { --venue-color: var(--venue-h); }

.venue-dot {
    display: inline-block;
    width: 8px;
    height: 8px;
    border-radius: 50%;
    background: var(--venue-color, var(--muted-text));
    flex: 0 0 auto;
}

/* --- pool chips ------------------------------------------------------- */

.chips {
    display: flex;
    flex-wrap: wrap;
    gap: 6px;
    margin: 0 0 14px;
}

.chip {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 4px 10px;
    border: 1px solid var(--venue-color, var(--control-border));
    border-left-width: 5px;
    border-radius: 999px;
    background: var(--card-bg);
    font-size: 0.78rem;
    white-space: nowrap;
}

.chip-venue,
.chip-count,
.chip-failed {
    color: var(--muted-text);
    font-variant-numeric: tabular-nums;
    font-size: 0.72rem;
}

.chip-failed {
    color: var(--sev-caution);
}

.chips-empty {
    margin: 0;
    font-size: 0.82rem;
    color: var(--muted-text);
}

/* --- controls --------------------------------------------------------- */

.controls {
    display: flex;
    flex-direction: column;
    gap: 10px;
    padding: 10px 12px;
    margin: 0 0 14px;
    border: 1px solid var(--panel-border);
    border-radius: 10px;
    background: var(--sunken-bg);
}

.control-field {
    display: flex;
    flex-direction: column;
    gap: 4px;
    min-width: 0;
}

.control-field label {
    font-size: 0.72rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted-text);
}

.control-field input,
.control-field select {
    padding: 7px 9px;
    border: 1px solid var(--control-border);
    border-radius: 8px;
    background: var(--control-bg);
    color: var(--control-text);
    font: inherit;
    font-size: 0.86rem;
    max-width: 100%;
}

.control-toggles {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: 10px;
}

.toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 0.9rem;
    font-weight: 600;
}

.ghost-button {
    padding: 7px 13px;
    border: 1px solid var(--control-border);
    border-radius: 8px;
    background: var(--control-bg);
    color: var(--control-text);
    font: inherit;
    font-size: 0.84rem;
    cursor: pointer;
}

.ghost-button:hover {
    border-color: var(--accent);
    color: var(--accent);
}

.ghost-button-small {
    padding: 4px 9px;
    font-size: 0.76rem;
}

.ghost-button[aria-pressed="true"] {
    border-color: var(--accent);
    color: var(--accent);
    font-weight: 600;
}

/* --- live state ------------------------------------------------------- */

.live-state {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding: 2px 10px;
    border-radius: 999px;
    border: 1px solid var(--control-border);
    font-size: 0.78rem;
    font-weight: 600;
    color: var(--muted-text);
}

.live-state-live {
    color: var(--up);
    border-color: var(--up);
}

.live-state-polling {
    color: var(--up);
    border-color: var(--up);
    font-variant-numeric: tabular-nums;
}

.live-state-connecting,
.live-state-reconnecting,
.live-state-hidden {
    color: var(--sev-caution);
    border-color: var(--sev-caution);
}

.live-counters {
    margin: 0;
    font-size: 0.8rem;
    color: var(--muted-text);
    font-variant-numeric: tabular-nums;
    line-height: 1.5;
}

.live-error {
    margin: 0;
    font-size: 0.8rem;
    color: var(--sev-critical);
    line-height: 1.5;
}

.live-note {
    margin: 0;
    font-size: 0.78rem;
    color: var(--muted-text);
    line-height: 1.5;
    max-width: 78ch;
}

/* The two live modes: stacked on a phone, so the long WebSocket caveat can wrap. */
.control-modes {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

.control-modes .toggle {
    align-items: flex-start;
    font-weight: 500;
    font-size: 0.82rem;
    line-height: 1.4;
}

/* --- the tape --------------------------------------------------------- */

.tape {
    list-style: none;
    margin: 0;
    padding: 0;
    border: 1px solid var(--panel-border);
    border-radius: 10px;
    overflow: hidden;
}

/* Mobile first: one card per trade, the fields wrapped into three lines. */
.tape-row {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto auto;
    grid-template-areas:
        "token side price"
        "venue size time"
        "tags tags link";
    gap: 2px 8px;
    padding: 8px 10px;
    border-bottom: 1px solid var(--panel-border);
    font-size: 0.86rem;
    background: var(--card-bg);
}

.tape-row:last-child {
    border-bottom: 0;
}

@keyframes tape-flash {
    from {
        background: var(--flash-bg);
    }

    to {
        background: var(--card-bg);
    }
}

.tape-row-new {
    animation: tape-flash 2s ease-out;
}

.tape-token {
    grid-area: token;
    display: flex;
    align-items: center;
    gap: 6px;
    font-weight: 700;
    min-width: 0;
}

.tape-venue {
    grid-area: venue;
    color: var(--muted-text);
    font-size: 0.78rem;
}

.tape-side {
    grid-area: side;
    font-weight: 600;
    white-space: nowrap;
}

.tape-side.side-buy {
    color: var(--up);
}

.tape-side.side-sell {
    color: var(--down);
}

.tape-side.side-unknown {
    color: var(--muted-text);
}

.tape-size {
    grid-area: size;
    color: var(--muted-text);
    font-size: 0.78rem;
}

.tape-price {
    grid-area: price;
    font-weight: 600;
    text-align: right;
}

.tape-price-quote {
    font-weight: 500;
    color: var(--muted-text);
}

.tape-time {
    grid-area: time;
    color: var(--muted-text);
    font-size: 0.78rem;
    text-align: right;
    white-space: nowrap;
}

.tape-tags {
    grid-area: tags;
    display: flex;
    gap: 5px;
    flex-wrap: wrap;
}

/* A suspect trade stays on the tape and in the count, but greyed: its numbers are known to be
   wrong, so it must not read like a measurement. */
.tape-row-suspect {
    opacity: 0.55;
}

.tape-row-suspect .tape-price,
.tape-row-suspect .tape-side {
    font-weight: 500;
    color: var(--muted-text);
}

.tape-tag {
    padding: 1px 7px;
    border: 1px solid var(--control-border);
    border-radius: 999px;
    font-size: 0.68rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted-text);
}

.tape-tag-suspect {
    border-color: var(--sev-caution);
    color: var(--sev-caution);
    text-transform: none;
    letter-spacing: 0;
}

.tape-link {
    grid-area: link;
    font-size: 0.78rem;
    white-space: nowrap;
    text-align: right;
}

.tape-link-missing {
    color: var(--muted-text);
}

.num {
    font-variant-numeric: tabular-nums;
}

/* --- the replay counters and timeline --------------------------------- */

.counters {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 6px;
    margin: 0 0 10px;
}

.counter {
    display: flex;
    flex-direction: column;
    gap: 1px;
    padding: 6px 9px;
    border: 1px solid var(--panel-border);
    border-radius: 8px;
    background: var(--card-bg);
    min-width: 0;
}

.counter-label {
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--muted-text);
}

.counter-value {
    font-size: 1rem;
    font-weight: 700;
    font-variant-numeric: tabular-nums;
    overflow-wrap: anywhere;
}

/* The timeline keeps its own scroll container, so the page never scrolls sideways. */
.timeline-scroll {
    overflow-x: auto;
    border: 1px solid var(--panel-border);
    border-radius: 10px;
    background: var(--card-bg);
    padding: 8px 6px 4px;
}

.timeline {
    display: block;
    width: 100%;
    min-width: 480px;
    height: 200px;
}

.bar-segment {
    fill: var(--venue-color, var(--muted-text));
}

.bar-empty {
    fill: var(--panel-border);
}

.bar-hatched {
    fill: url(#hatch);
    opacity: 0.5;
}

.hatch-line {
    stroke: var(--muted-text);
    stroke-width: 1.5;
}

.axis-label {
    fill: var(--muted-text);
    font-size: 11px;
    font-family: system-ui, sans-serif;
    text-anchor: middle;
}

.cursor {
    stroke: var(--accent);
    stroke-width: 2;
}

.caption {
    margin: 8px 0 8px;
    font-size: 0.8rem;
    line-height: 1.5;
    color: var(--muted-text);
    max-width: 82ch;
}

.legend {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
}

.legend-item {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    font-size: 0.78rem;
}

/* --- methodology and foot --------------------------------------------- */

.notes-list {
    margin: 0;
    padding-left: 20px;
    max-width: 82ch;
}

.notes-list li {
    margin: 0 0 10px;
    font-size: 0.86rem;
    line-height: 1.55;
}

.page-foot {
    margin: 28px 0 0;
    padding-top: 12px;
    border-top: 1px solid var(--panel-border);
    font-size: 0.8rem;
    color: var(--muted-text);
}

/* --- reduced motion --------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
    /* The highlight still marks a new row, but it lands rather than fades: the class is removed on
       animationend, so the duration must stay above zero for the listener to fire. */
    .tape-row-new {
        animation-duration: 0.01s;
    }
}

/* --- wider screens ---------------------------------------------------- */

@media (min-width: 560px) {
    .counters {
        grid-template-columns: repeat(5, minmax(0, 1fr));
    }

    .controls {
        flex-direction: row;
        flex-wrap: wrap;
        align-items: flex-end;
    }

    .control-field {
        flex: 1 1 260px;
    }

    /* A two-option select does not need the width a URL field does. */
    #replaySection .control-field {
        flex: 0 1 11rem;
    }

    .control-modes,
    .live-counters,
    .live-error,
    .live-note {
        flex: 1 1 100%;
    }

    /* Side by side once there is room; the caveat text still wraps inside its own label. */
    .control-modes {
        flex-direction: row;
        flex-wrap: wrap;
        gap: 14px;
    }

    .control-modes .toggle {
        flex: 1 1 18rem;
    }
}

@media (min-width: 760px) {
    body {
        margin: 24px;
    }

    h1 {
        font-size: 1.6rem;
    }

    /* One line per trade once there is room: time, token, venue, side, size, price, tags, link. */
    .tape-row {
        grid-template-columns: 5.5rem minmax(4.5rem, 7rem) minmax(4rem, 8rem) 5.5rem minmax(4rem, 7rem) minmax(5rem, 8rem) minmax(0, 1fr) auto;
        grid-template-areas: "time token venue side size price tags link";
        align-items: center;
        gap: 10px;
    }

    .tape-time {
        text-align: left;
    }

    .tape-price {
        text-align: right;
    }

    .tape-size {
        text-align: right;
        font-size: 0.82rem;
    }

    .tape-venue {
        font-size: 0.82rem;
    }
}
