/* ==========================================
   Soft Scanner watchlist compare board (P7 Task 4)
   Source mockup: docs/superpowers/specs/2026-07-18-redesign-mockups/softc-3-watchlist.html
   panel W2, in auctionviewer. Linked from watchlist.html only, after
   styles.css, so nothing here reaches the pages that still run the old chrome.

   Every colour comes from tokens.css -- there are no literal hex values in
   this file, so both themes follow the token flip automatically.

   The mockup wrapped its table in `overflow-x:auto; min-width:430px`. That is
   deliberately NOT reproduced: "no horizontal body scroll at 375px" is a hard
   exit criterion for this phase, so the table is `table-layout: fixed` at
   100% width and the two widest columns are dropped below 820px instead.
   ========================================== */

/* ==========================================
   Board wrapper + table
   ========================================== */
.wb {
    max-width: 100%;
    padding: 0 10px 14px;
}

/* border-spacing gives each row the gap the mockup's card rows had; the cell
   backgrounds below turn each <tr> into a card. table-layout:fixed is what
   guarantees a long unbreakable title can never widen the table past its
   container -- the Item cell ellipsizes instead. */
.wb-table {
    width: 100%;
    table-layout: fixed;
    border-collapse: separate;
    border-spacing: 0 7px;
}

.wb-th {
    padding: 0;
    color: var(--dim);
    font-family: var(--mono);
    font-size: .58rem;
    font-weight: 600;
    letter-spacing: .08em;
    text-align: left;
    text-transform: uppercase;
}

/* Fixed column widths, read from the header row. The Item column takes
   whatever is left. Sized so Item still gets ~180px inside a 375px viewport
   once Trend and Limit are hidden. */
.wb-c-now { width: 88px; }
.wb-c-trend { width: 64px; }
.wb-c-ends { width: 76px; }
.wb-c-limit { width: 84px; }

/* Full-cell hit area: the header text is tiny, the tap target is not. */
.wb-sort {
    display: flex;
    align-items: center;
    gap: 4px;
    width: 100%;
    min-height: 40px;
    padding: 0 8px;
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.wb-sort:hover {
    color: var(--ink);
}

/* The active sort column, driven by the aria-sort the view already sets --
   no extra class needed to keep the two in step. */
.wb-th[aria-sort="ascending"],
.wb-th[aria-sort="descending"] {
    color: var(--ink);
}

.wb-empty {
    padding: 48px 20px;
    color: var(--dim);
    font-size: .9rem;
    text-align: center;
}

/* ==========================================
   Rows

   Each <td> carries the card surface; the outer border is split across the
   first and last cell so a `border-collapse: separate` row still reads as one
   rounded card (the same card/line/radius idiom as browse.css's .row).
   ========================================== */
.wb-row {
    cursor: pointer;
}

.wb-row > td {
    padding: 9px 10px;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    background: var(--card);
    font-size: .76rem;
    vertical-align: middle;
    transition: border-color .15s;
}

.wb-row > td:first-child {
    border-left: 1px solid var(--line);
    border-radius: 12px 0 0 12px;
}

.wb-row > td:last-child {
    border-right: 1px solid var(--line);
    border-radius: 0 12px 12px 0;
}

.wb-row:hover > td,
.wb-row.is-open > td {
    border-color: var(--sage);
}

/* An item whose auction has crossed zero while the ticker was running. It
   stays put until the next render moves it to the Ended section. */
.wb-row.is-ended > td {
    opacity: .65;
}

/* Missing from the latest scrape: the row keeps its last-known values and
   says so via .wb-stale-note rather than vanishing. */
.wb-row.is-stale > td {
    background: var(--bg);
}

/* ==========================================
   Item cell

   Markup contract: .wb-c-item holds exactly ONE child element (the row's
   expand <button>), which in turn holds .wb-thumb, .wb-title and -- when the
   row is stale -- .wb-stale-note. Laying the child out rather than the <td>
   keeps the cell a real table-cell, so table-layout:fixed still applies the
   column width to it.
   ========================================== */
.wb-c-item > * {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 3px 9px;
    width: 100%;
    min-width: 0;
    min-height: 40px;
    padding: 0;
    border: none;
    background: none;
    color: inherit;
    font: inherit;
    text-align: left;
    cursor: pointer;
}

.wb-thumb {
    flex: none;
    width: 34px;
    height: 34px;
    border-radius: 9px;
    background: var(--bg);
    display: grid;
    place-items: center;
    font-size: 1.05rem;
    overflow: hidden;
}

.wb-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
}

.wb-title {
    /* basis 0, not auto: a content-sized basis lets an oversized title wrap to
       a second flex line and sit under the thumb instead of shrinking and
       ellipsizing beside it. */
    flex: 1 1 0;
    min-width: 0;
    overflow: hidden;
    font-size: .78rem;
    font-weight: 700;
    line-height: 1.25;
    white-space: nowrap;
    text-overflow: ellipsis;
}

/* Wraps onto its own line under the thumb -- an indent matched to the thumb
   width would only be one more thing to keep in sync. */
.wb-stale-note {
    flex: 1 1 100%;
    color: var(--dim);
    font-size: .62rem;
    font-weight: 400;
}

/* ==========================================
   Now / Trend / Ends / Limit cells

   Rising price is --clay because it is bad news for a buyer; falling is
   --sage-deep. Same semantics as the mockup, and the same pairing browse.css
   already uses for .rbids .up / .dn.
   ========================================== */
.wb-price {
    display: block;
    font-family: var(--mono);
    font-size: .74rem;
    font-weight: 700;
}

.wb-delta {
    display: block;
    margin-top: 2px;
    font-family: var(--mono);
    font-size: .62rem;
}

.wb-delta.up { color: var(--clay); }
.wb-delta.down { color: var(--sage-deep); }
.wb-delta.same { color: var(--dim); }

/* The polyline/dot inherit the sparkline's own colour, so the view only has
   to put the trend modifier on the <svg>. */
.wb-spark {
    display: block;
    color: var(--dim);
}

.wb-spark polyline,
.wb-spark line,
.wb-spark circle {
    stroke: currentColor;
}

.wb-spark.up { color: var(--clay); }
.wb-spark.down { color: var(--sage-deep); }
.wb-spark.same { color: var(--dim); }

/* The 0-point state: an em dash, never an invented trend. */
.wb-spark-none {
    color: var(--dim);
    font-family: var(--mono);
    font-size: .72rem;
}

.wb-ends {
    font-family: var(--mono);
    font-size: .72rem;
}

.wb-ends.is-urgent {
    color: var(--clay);
    font-weight: 700;
}

.wb-limit {
    font-family: var(--mono);
    font-size: .68rem;
    color: var(--sage-deep);
}

.wb-limit.over {
    color: var(--clay);
    font-weight: 700;
}

.wb-limit.none {
    color: var(--dim);
}

/* ==========================================
   Expanded action strip

   A full-width <tr> following the row it belongs to. Its cell is transparent
   and unpadded so .wb-exp-inner is the only visible surface.
   ========================================== */
.wb-exp > td {
    padding: 0;
    background: none;
}

.wb-exp-inner {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 12px;
    padding: 12px;
    border: 1px solid var(--sage);
    border-radius: 12px;
    background: var(--card);
}

/* The Trend + Limit recap for the two columns hidden on mobile. Desktop shows
   those columns in the row itself, so it has nothing to recap. */
.wb-exp-recap {
    display: none;
    flex: 1 1 100%;
    align-items: center;
    gap: 14px;
}

.wb-limit-editor {
    display: flex;
    flex: 1 1 100%;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px;
    font-size: .78rem;
}

.wb-limit-editor label {
    color: var(--dim);
    font-weight: 700;
}

.wb-limit-input {
    width: 110px;
    min-height: 40px;
    padding: 8px 10px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: var(--card);
    color: var(--ink);
    font-family: var(--mono);
    font-size: .82rem;
}

.wb-limit-editor button {
    min-height: 40px;
    padding: 0 16px;
    border: 1px solid var(--line);
    border-radius: 999px;
    background: var(--bg);
    color: var(--ink);
    font: inherit;
    font-size: .78rem;
    font-weight: 700;
    cursor: pointer;
}

.wb-limit-editor button:hover {
    border-color: var(--sage);
}

/* Validation message. --clay carries the "something is wrong" signal as a
   border rather than as the text colour, which keeps the copy itself at full
   --ink contrast in both themes. */
.wb-err {
    flex: 1 1 100%;
    padding: 6px 10px;
    border-left: 3px solid var(--clay);
    border-radius: 8px;
    background: var(--clay-soft);
    color: var(--ink);
    font-size: .72rem;
}

.wb-notify {
    display: flex;
    flex: 1 1 100%;
    align-items: center;
    gap: 10px;
    min-height: 40px;
    font-size: .8rem;
    font-weight: 700;
    cursor: pointer;
}

.wb-notify input[type="checkbox"] {
    flex: none;
    width: 18px;
    height: 18px;
    accent-color: var(--sage);
}

/* P8 owns delivery; this line is what keeps the toggle honest. */
.wb-notify-help {
    display: block;
    margin-top: 2px;
    color: var(--dim);
    font-size: .68rem;
    font-weight: 400;
}

/* --bar-bg/--bar-fg rather than --sage-deep: those two are the palette's
   theme-stable inverted pair (7.8:1), where sage flips light in dark mode and
   would leave light text on a light pill. */
.wb-bid {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    min-height: 40px;
    padding: 0 16px;
    border: none;
    border-radius: 999px;
    background: var(--bar-bg);
    color: var(--bar-fg);
    font-size: .78rem;
    font-weight: 800;
    text-decoration: none;
}

.wb-remove,
.wb-clear-ended {
    min-height: 40px;
    padding: 0 16px;
    border: 1px solid var(--clay);
    border-radius: 999px;
    background: none;
    color: var(--ink);
    font: inherit;
    font-size: .78rem;
    font-weight: 700;
    cursor: pointer;
}

.wb-remove:hover,
.wb-clear-ended:hover {
    background: var(--clay-soft);
}

/* ==========================================
   Ended section
   ========================================== */
.wb-ended {
    margin: 18px 10px 0;
    border: 1px solid var(--line);
    border-radius: var(--r);
    background: var(--card);
}

.wb-ended-summary {
    display: flex;
    align-items: center;
    gap: 10px;
    min-height: 44px;
    padding: 10px 14px;
    color: var(--dim);
    font-size: .8rem;
    font-weight: 700;
    cursor: pointer;
}

.wb-ended-row {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 10px;
    padding: 10px 14px;
    border-top: 1px solid var(--line);
    font-size: .78rem;
}

/* The title inside an ended row -- everything else in the row is fixed-width,
   so this is what absorbs the remaining space and ellipsizes. */
.wb-ended-row > span:first-child {
    flex: 1 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
}

.wb-result {
    flex: none;
    padding: 3px 8px;
    border-radius: 7px;
    background: var(--sage-soft);
    color: var(--sage-deep);
    font-family: var(--mono);
    font-size: .66rem;
    font-weight: 700;
}

/* "sold under your $40 limit". --honey as a rule rather than as the text
   colour: honey on --honey-soft is barely 1.7:1, --ink on it is ~11:1. */
.wb-callout {
    flex: 1 1 100%;
    padding: 6px 10px;
    border-left: 3px solid var(--honey);
    border-radius: 8px;
    background: var(--honey-soft);
    color: var(--ink);
    font-size: .72rem;
    font-weight: 700;
}

/* The "went over your limit" case -- same slot, deliberately muted. */
.wb-callout.over {
    border-left-color: var(--line);
    background: var(--bg);
    color: var(--dim);
    font-weight: 400;
}

/* ==========================================
   Toast (limit save failed -> reverted)
   ========================================== */
.wb-toast {
    position: fixed;
    left: 16px;
    right: 16px;
    bottom: calc(84px + env(safe-area-inset-bottom));
    z-index: 90;
    max-width: 360px;
    margin-inline: auto;
    padding: 12px 16px;
    border-radius: var(--r);
    background: var(--bar-bg);
    color: var(--bar-fg);
    box-shadow: var(--shadow);
    font-size: .82rem;
    font-weight: 700;
    text-align: center;
}

/* ==========================================
   Mobile

   Same breakpoint as browse.css. Dropping Trend and Limit leaves three
   columns (Item, Now, Ends), which is what keeps the board inside a 375px
   viewport without a scroller. Both the <th> and the <td> carry the .wb-c-*
   class, so one selector hides the whole column.
   ========================================== */
@media (max-width: 819.98px) {
    .wb-c-trend,
    .wb-c-limit {
        display: none;
    }

    .wb-c-now { width: 78px; }
    .wb-c-ends { width: 66px; }

    .wb-exp-recap {
        display: flex;
    }

    .wb-limit-input {
        /* Under 16px iOS zooms the whole page on focus, which on a fixed-width
           board reads as a layout break. */
        font-size: 1rem;
    }
}

/* ==========================================
   Desktop
   ========================================== */
@media (min-width: 820px) {
    .wb,
    .wb-ended {
        max-width: 760px;
        margin-left: auto;
        margin-right: auto;
    }
}

@media (prefers-reduced-motion: reduce) {
    .wb-row > td {
        transition: none;
    }
}
