/* ============================================
   Single Lineup Simulation — results panel

   A slide-over from the right, over the player grid. It mounts on <body>,
   NOT inside .panel-right, because renderLineupBuilderPreview() replaces that
   panel's contents on every lock/unlock and would destroy anything in it.

   The builder's preview card stays visible to the left, which is the point:
   the loop is change a player, look, change it back.
   ============================================ */

/* The panel covers the PLAYER GRID and stops short of the builder's preview
   card, so the lineup being judged stays on screen next to its verdict. An
   earlier version slid over from the right and covered the preview card — the
   one thing the user needs to see.

   --ssim-top and --ssim-right are set from JS at open time (see setGeometry):
   measured off the real site header and .panel-right rather than hardcoded, so
   a header or layout change does not silently misplace this. The values here
   are the fallback if measuring fails. */
.ssim-panel {
    position: fixed;
    top: var(--ssim-top, 65px);
    left: 0;
    right: var(--ssim-right, 400px);
    bottom: 0;
    z-index: 1040; /* under the site header (1050) so nav stays reachable */
    display: flex;
    flex-direction: column;
    background: var(--liq-bg-primary);
    border-right: 1px solid var(--liq-border-color);
    box-shadow: 4px 0 24px var(--liq-shadow);
    transform: translateX(-100%);
    transition: transform 0.18s ease-out;
    overflow: hidden;
}

.ssim-panel.is-open {
    transform: translateX(0);
}

@media (prefers-reduced-motion: reduce) {
    .ssim-panel {
        transition: none;
    }
}

.ssim-header {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0.75rem 1rem;
    background: var(--liq-bg-secondary);
    border-bottom: 1px solid var(--liq-border-color);
    flex: 0 0 auto;
}

.ssim-title {
    font-weight: 600;
    color: var(--liq-text-primary);
}

.ssim-close {
    background: none;
    border: none;
    font-size: 1.5rem;
    line-height: 1;
    color: var(--liq-text-secondary);
    cursor: pointer;
    padding: 0 0.25rem;
}

.ssim-close:hover {
    color: var(--liq-text-primary);
}

.ssim-body {
    flex: 1 1 auto;
    overflow-y: auto;
    padding: 1rem;
}

/* ---- Contest selector ---- */

.ssim-contest {
    margin-bottom: 1rem;
}

.ssim-contest-label {
    display: block;
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--liq-text-muted);
    margin-bottom: 0.25rem;
}

/* ---- Stale banner ----
   The roster changed but the old numbers stay on screen, dimmed. Clearing
   them would destroy the comparison the user is in the middle of making. */

.ssim-stale {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.5rem;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.75rem;
    border: 1px solid var(--liq-accent-yellow);
    background: var(--liq-accent-yellow-hover);
    border-radius: 0.375rem;
    font-size: 0.875rem;
    color: var(--liq-text-primary);
}

.ssim-metrics.is-stale,
.ssim-scores.is-stale {
    opacity: 0.45;
}

/* An ROI whose interval straddles break-even has not answered the question.
   Offer the extra iterations rather than imposing 23 more seconds unasked. */
.ssim-ambiguous {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 0.625rem;
    padding: 0.5rem 0.75rem;
    margin-bottom: 0.625rem;
    border: 1px solid var(--liq-accent-blue);
    background: var(--liq-accent-blue-hover);
    border-radius: 0.375rem;
    font-size: 0.75rem;
    line-height: 1.4;
    color: var(--liq-text-primary);
}

.ssim-refine {
    flex: 0 0 auto;
    white-space: nowrap;
    background: var(--liq-accent-blue);
    border: 1px solid var(--liq-accent-blue);
    color: #fff;
}

.ssim-refine:hover {
    filter: none;
    background: #2f6fd0;
    border-color: #2f6fd0;
    color: #fff;
}

/* ---- Metric tiles ---- */

/* The verdict runs four across, full width, above the chart. */
.ssim-metrics {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 0.375rem;
    margin-bottom: 0.625rem;
}

/* The score percentiles sit beside the roster, so two across in the narrower
   column. They pair naturally with it: these four numbers are what that roster
   is worth. */
.ssim-scores {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: 0.375rem;
}

.ssim-metric {
    padding: 0.5rem 0.625rem;
    background: var(--liq-bg-secondary);
    border: 1px solid color-mix(in srgb, var(--liq-border-color) 60%, transparent);
    border-radius: 0.375rem;
    min-width: 0;
}

@supports not (border: 1px solid color-mix(in srgb, red 50%, transparent)) {
    .ssim-metric {
        border-color: var(--liq-border-color);
    }
}

.ssim-metric-value {
    font-size: 1.25rem;
    font-weight: 600;
    line-height: 1.1;
    letter-spacing: -0.01em;
    color: var(--liq-text-primary);
    font-variant-numeric: tabular-nums;
}

.ssim-metric.is-good .ssim-metric-value {
    color: var(--liq-accent-green);
}

.ssim-metric.is-bad .ssim-metric-value {
    color: var(--liq-accent-red);
}

.ssim-metric-label {
    font-size: 0.6875rem;
    font-weight: 600;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--liq-text-secondary);
    margin-top: 0.1875rem;
}

.ssim-metric-sub {
    font-size: 0.625rem;
    color: var(--liq-text-muted);
    margin-top: 0.125rem;
    line-height: 1.35;
}

/* ---- Finish-distribution chart ----
   21 bars: 0-1%, then 1-5%, 5-10% ... 95-100%. The split first bar matters:
   in a top-heavy GPP nearly all the ROI lives in the top 1%, and a plain 0-5
   bar hides the difference between winning and merely finishing well. */

.ssim-chart {
    margin-bottom: 0.875rem;
}

.ssim-chart-head {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    margin-bottom: 0.375rem;
}

.ssim-chart-title {
    font-size: 0.8125rem;
    font-weight: 600;
    color: var(--liq-text-primary);
}

.ssim-chart-legend {
    font-size: 0.6875rem;
    color: var(--liq-text-muted);
}

.ssim-key {
    display: inline-block;
    width: 0.625rem;
    height: 0.625rem;
    border-radius: 2px;
    margin: 0 0.25rem 0 0.5rem;
    vertical-align: -1px;
}

.ssim-key.is-cash {
    background: var(--liq-accent-green);
}

.ssim-key.is-nocash {
    background: var(--liq-text-muted);
}

/* ---- Roster beside the chart ----
   At ~780px there is room for both, and seeing which seats are chalk next to
   the shape they produce is the point of having them on one screen. */

.ssim-split {
    display: flex;
    gap: 0.875rem;
    align-items: flex-start;
    margin-bottom: 1rem;
}

.ssim-split-left {
    flex: 0 0 22rem;
    min-width: 0;
}

.ssim-split-right {
    flex: 1 1 auto;
    min-width: 0;
}

/* No cell borders and no centred text: a roster is a LIST, and ruling every
   cell turns nine rows into a spreadsheet. One rule under the header, one over
   the totals, and hierarchy carried by weight and colour instead. */
.ssim-roster {
    width: 100%;
    border-collapse: collapse;
    font-size: 0.8125rem;
    font-variant-numeric: tabular-nums;
}

/* NO text-transform: uppercase here. It rendered "pOwn" as "POWN" and "Fpts"
   as "FPTS", which is how the header ended up looking cheap — these are proper
   names with meaningful casing, not shout-case labels. Sentence case, a real
   reading size, and enough contrast to be a header rather than a whisper. */
.ssim-roster th {
    text-align: left;
    font-weight: 600;
    color: var(--liq-text-secondary);
    font-size: 0.6875rem;
    letter-spacing: 0.01em;
    padding: 0 0.375rem 0.4375rem;
    white-space: nowrap;
    /* `border: none` FIRST. A site-level th rule puts a border on ALL FOUR
       sides; overriding only the bottom left the top and the verticals showing,
       which is exactly what made this read as a raw HTML table. One rule under
       the header and nothing else. */
    border: none;
    border-bottom: 1px solid var(--liq-border-color);
    background: none;
}

/* Alignment is set explicitly: a site-level rule centres td, which turns a
   roster into a ragged column of names floating in the middle of the cell. */
.ssim-roster td {
    padding: 0.3125rem 0.375rem;
    color: var(--liq-text-primary);
    border: none;
    text-align: left;
}

.ssim-roster tbody tr {
    border-bottom: 1px solid color-mix(in srgb, var(--liq-border-color) 45%, transparent);
}

@supports not (border-bottom: 1px solid color-mix(in srgb, red 50%, transparent)) {
    .ssim-roster tbody tr {
        border-bottom: 1px solid var(--liq-bg-tertiary);
    }
}

.ssim-roster tbody tr:last-child {
    border-bottom: none;
}

.ssim-roster tbody tr:hover {
    background: var(--liq-bg-hover);
}

.ssim-roster tfoot td {
    border-top: 1px solid var(--liq-border-color);
    padding-top: 0.4375rem;
    font-size: 0.75rem;
    color: var(--liq-text-muted);
}

/* Position as a chip: it is a label, not data, and a chip stops it competing
   with the player name for attention. */
.ssim-roster .ssim-r-slot {
    width: 2.75rem;
    text-align: left;
}

.ssim-pos {
    display: inline-block;
    min-width: 2.125rem;
    text-align: center;
    padding: 0.0625rem 0.25rem;
    border-radius: 0.1875rem;
    background: var(--liq-bg-tertiary);
    color: var(--liq-text-secondary);
    font-size: 0.625rem;
    font-weight: 600;
    letter-spacing: 0.02em;
}

.ssim-r-name {
    max-width: 7rem;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    font-weight: 500;
}

.ssim-roster .ssim-r-opp {
    color: var(--liq-text-muted);
    font-size: 0.75rem;
    width: 2.5rem;
    text-align: left;
}

.ssim-roster .ssim-r-sal {
    text-align: right;
    color: var(--liq-text-secondary);
    width: 3.5rem;
}

/* Ownership: the number, with a bar behind it scaled to the chalkiest seat on
   the roster. Turns a column of numbers into something scannable — which seat
   is the chalk is the question being asked of this column. */
.ssim-roster .ssim-r-own {
    position: relative;
    text-align: right;
    width: 3.75rem;
    isolation: isolate;
}

/* Projected points: the other half of "is this seat worth its salary", and the
   number the score percentiles above are built from. */
.ssim-roster .ssim-r-fpts {
    text-align: right;
    width: 2.75rem;
    font-weight: 500;
}

.ssim-roster tfoot .ssim-r-fpts {
    font-weight: 600;
    color: var(--liq-text-secondary);
}

.ssim-own-bar {
    position: absolute;
    right: 0.375rem;
    top: 50%;
    transform: translateY(-50%);
    height: 1.125rem;
    width: var(--w, 0%);
    max-width: calc(100% - 0.75rem);
    background: var(--liq-accent-blue);
    opacity: 0.16;
    border-radius: 0.125rem;
    z-index: -1;
}

.ssim-own-val {
    position: relative;
    color: var(--liq-text-primary);
}

.ssim-roster tfoot .ssim-own-val {
    color: var(--liq-text-secondary);
    font-weight: 600;
}

@media (max-width: 1023.98px) {
    .ssim-split {
        flex-direction: column;
    }

    .ssim-split-left {
        flex: 1 1 auto;
        width: 100%;
    }
}

/* Plot = y-axis gutter + the bars. */
.ssim-plot {
    display: flex;
    align-items: stretch;
    gap: 0.375rem;
}

.ssim-yaxis {
    position: relative;
    flex: 0 0 3.25rem;
    height: 150px;
}

.ssim-ytick {
    position: absolute;
    right: 0;
    width: 100%;
    border-top: 1px dashed var(--liq-border-color);
    font-size: 0.625rem;
    color: var(--liq-text-muted);
    text-align: right;
    line-height: 1;
    transform: translateY(50%);
}

.ssim-ytick span {
    background: var(--liq-bg-primary);
    padding-left: 0.25rem;
    font-variant-numeric: tabular-nums;
}

.ssim-bars {
    position: relative;
    flex: 1 1 auto;
    display: flex;
    align-items: flex-end;
    /* 100 bars: no gap, or the gaps take more width than the data. */
    gap: 0;
    height: 150px;
    padding-top: 2px;
    border-bottom: 1px solid var(--liq-border-color);
    border-left: 1px solid var(--liq-border-color);
}

.ssim-ylabel {
    display: flex;
    justify-content: space-between;
    gap: 0.5rem;
    font-size: 0.625rem;
    color: var(--liq-text-muted);
    margin-top: 0.125rem;
}

/* The axis is a finish POSITION: low is good, which is the opposite of the
   everyday "99th percentile is excellent" reading. Worth saying on the chart. */
.ssim-dir {
    color: var(--liq-text-secondary);
    white-space: nowrap;
}

.ssim-bar-slot {
    flex: 1 1 0;
    height: 100%;
    display: flex;
    align-items: flex-end;
}

.ssim-bar {
    width: 100%;
    height: var(--ssim-h, 0%);
    min-height: 1px;
    background: var(--liq-text-muted);
}

.ssim-bar-slot:hover .ssim-bar {
    filter: brightness(1.25);
}

.ssim-bar.is-cash {
    background: var(--liq-accent-green);
}

/* The bar the cash line falls inside. The gradient stop is the TRUE cash
   percentile within this bucket, so the boundary is drawn where it actually
   is rather than snapped to the nearest bar edge. */
.ssim-bar.is-split {
    background: linear-gradient(
        to right,
        var(--liq-accent-green) 0,
        var(--liq-accent-green) var(--ssim-split, 50%),
        var(--liq-text-muted) var(--ssim-split, 50%),
        var(--liq-text-muted) 100%
    );
}

.ssim-cashline {
    position: absolute;
    top: 0;
    bottom: 0;
    width: 0;
    border-left: 1px dashed var(--liq-text-primary);
    opacity: 0.55;
    pointer-events: none;
}

.ssim-axis {
    display: flex;
    justify-content: space-between;
    font-size: 0.6875rem;
    color: var(--liq-text-muted);
    margin-top: 0.25rem;
}

.ssim-reading {
    font-size: 0.75rem;
    color: var(--liq-text-secondary);
    line-height: 1.4;
    margin-top: 0.5rem;
}

/* ---- Notes and provenance ---- */

.ssim-note {
    font-size: 0.75rem;
    line-height: 1.45;
    color: var(--liq-text-secondary);
    background: var(--liq-bg-tertiary);
    border-radius: 0.375rem;
    padding: 0.625rem 0.75rem;
    margin-bottom: 1rem;
}

/* ---- Run history ----
   Closing the panel or editing the roster must not throw a verdict away: the
   loop is swap a player, see if it improved, often swap back. Each row says
   what was different about that roster and what it cost or gained. */

.ssim-history {
    margin-top: 0.75rem;
}

.ssim-history-title {
    font-size: 0.75rem;
    text-transform: uppercase;
    letter-spacing: 0.03em;
    color: var(--liq-text-muted);
    margin-bottom: 0.375rem;
}

.ssim-hist-row {
    display: flex;
    align-items: center;
    gap: 0.625rem;
    width: 100%;
    text-align: left;
    padding: 0.375rem 0.5rem;
    margin-bottom: 0.25rem;
    background: var(--liq-bg-secondary);
    border: 1px solid var(--liq-border-color);
    border-radius: 0.3125rem;
    cursor: pointer;
    font-size: 0.8125rem;
    color: var(--liq-text-primary);
}

.ssim-hist-row:hover {
    background: var(--liq-bg-hover);
}

.ssim-hist-row.is-current {
    border-color: var(--liq-accent-green);
    cursor: default;
}

.ssim-hist-roi {
    flex: 0 0 4.25rem;
    font-weight: 600;
    font-variant-numeric: tabular-nums;
}

.ssim-hist-label {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

.ssim-hist-contest {
    display: block;
    font-size: 0.6875rem;
    color: var(--liq-text-muted);
}

.ssim-hist-delta {
    flex: 0 0 auto;
    font-size: 0.6875rem;
    font-variant-numeric: tabular-nums;
}

.ssim-hist-delta.is-up {
    color: var(--liq-accent-green);
}

.ssim-hist-delta.is-down {
    color: var(--liq-accent-red);
}

/* ---- Ownership column in the builder preview card ----
   So chalk is visible while the lineup is being built, not only after a sim.
   Resolved from the same source the grid and the sim use. */

.lineup-card-table .col-own {
    text-align: right;
    white-space: nowrap;
    font-variant-numeric: tabular-nums;
    color: var(--liq-text-secondary);
}

.lineup-card-table thead .col-own {
    color: var(--liq-text-muted);
}

/* A roster that already has a verdict: the way back to it after closing. An
   outline button, so it reads as "view again" rather than "run again" — with a
   real filled hover of its own instead of inheriting a filter. */
.lineup-builder-footer .btn-sim-lineup.has-result {
    background: transparent;
    color: var(--liq-accent-green);
    border-color: var(--liq-accent-green);
}

.lineup-builder-footer .btn-sim-lineup.has-result:hover:not(:disabled),
.lineup-builder-footer .btn-sim-lineup.has-result:focus-visible:not(:disabled) {
    background: var(--liq-accent-green);
    border-color: var(--liq-accent-green);
    color: #fff;
}

.ssim-provenance {
    font-size: 0.6875rem;
    color: var(--liq-text-muted);
    border-top: 1px solid var(--liq-border-color);
    padding-top: 0.5rem;
}

/* ---- Loading and error ---- */

.ssim-loading {
    padding: 2rem 0;
    text-align: center;
}

.ssim-loading-label {
    font-size: 0.875rem;
    color: var(--liq-text-secondary);
    margin-bottom: 0.5rem;
}

.ssim-progress-pct {
    margin-left: 0.375rem;
    font-variant-numeric: tabular-nums;
}

.ssim-progress {
    height: 4px;
    background: var(--liq-bg-tertiary);
    border-radius: 2px;
    overflow: hidden;
    margin-bottom: 1rem;
}

.ssim-progress-bar {
    height: 100%;
    width: 0;
    background: var(--liq-accent-green);
    transition: width 0.15s linear;
}

.ssim-error {
    padding: 1.5rem 1rem;
    font-size: 0.875rem;
    color: var(--liq-text-secondary);
    text-align: center;
    line-height: 1.5;
}

.ssim-gen-field {
    display: block;
    margin: 0.875rem auto 0;
    background: var(--liq-accent-green);
    border: 1px solid var(--liq-accent-green);
    color: #fff;
}

.ssim-gen-field:hover {
    background: #0e9f70;
    border-color: #0e9f70;
    color: #fff;
}

/* ---- The button in the builder preview footer ---- */

.btn-sim-lineup {
    background: var(--liq-accent-green);
    border: 1px solid var(--liq-accent-green);
    color: #fff;
    transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease;
}

/* An explicit darker green, NOT filter: brightness(). The filter did nothing
   useful on the outlined has-result state below — a transparent background has
   no brightness to reduce, so hovering just dimmed the text and looked broken
   in both themes. */
.btn-sim-lineup:hover:not(:disabled),
.btn-sim-lineup:focus-visible:not(:disabled) {
    background: #0e9f70;
    border-color: #0e9f70;
    color: #fff;
}

.btn-sim-lineup:disabled {
    opacity: 0.5;
}

/* ---- Narrow viewports ----
   The run is cut to 1,000 field lineups and 5,000 iterations on a phone
   (see LineupIQSingleSim.sizing) because the work is real: a mid-range phone
   is several times slower than a desktop. */

/* ONE BREAKPOINT: 1023.98px, the LineupIQ standard set by the 2026-09-18
   responsive review. Narrow stacks the workspace, so there is no preview card
   beside us to leave room for. */
@media (max-width: 1023.98px) {
    .ssim-panel {
        right: 0;
    }
}

@media (max-width: 1023.98px) {
    /* The label carries the meaning; the sub-line doubles each tile's height
       and the narrow layout has no room to spare. */
    .ssim-metric-sub {
        display: none;
    }
}

/* ---- Builder footer: four buttons no longer fit one row ----
   Sim This Lineup is the primary action, so it takes its own full-width row
   under the three secondary ones instead of squeezing a fourth into the flex
   line. Kept HERE rather than in views.css so this feature owns its own CSS. */

.lineup-builder-footer {
    flex-wrap: wrap;
}

.lineup-builder-footer .btn-sim-lineup {
    flex: 1 0 100%;
    margin-top: 0.25rem;
    font-weight: 600;
}
