/* Page wrapper is the shared .page (main.css) — #card-drawer sizes against it. */

/* ── Content ── */
.prices-content {
    flex: 1;
    display: grid;
    grid-template-columns: 1fr 2fr;
    /* Search panel gets a bit less than an even split at rest — it still
       grows to 1.65fr on hover/focus (see below), just starts smaller. */
    grid-template-rows: 1.2fr 0.8fr;
    grid-template-areas:
        "watchlist graph"
        "watchlist search";
    gap: 16px;
    overflow: hidden;
    min-height: 0;
    padding: 32px;
    /* ease-out (not ease) so the reverse-on-hover-out reads as an immediate
       stop-and-reverse rather than a slow wind-down — CSS transitions
       already restart from whatever size the row is currently at when the
       hover/focus state flips mid-animation, this just makes that feel
       snappier. Shortened from 0.25s for the same reason. */
    transition: grid-template-rows 0.18s ease-out;
}

/* While the search panel is being used — typing, or just hovered — grow it
   into the graph panel's row for a bigger results view. Reverts the instant
   focus/hover leaves, so the graph stays the default larger panel otherwise.
   The third selector covers the Add to Watchlist modal (#watchlist-add-modal,
   opened from a search result tile): it's a `position: fixed` overlay
   covering the whole viewport, so while it's open the pointer is technically
   hovering the overlay, not .prices-search-panel underneath it — without this,
   the row would collapse for as long as the modal stays open and then
   immediately re-expand (an unwanted collapse/re-expand flash) the moment it
   closes back over a still-hovered search panel. */
.prices-content:has(.prices-search-panel:hover),
.prices-content:has(.prices-search-panel:focus-within),
.prices-page:has(#watchlist-add-modal:not(.hidden)) .prices-content {
    grid-template-rows: 0.35fr 1.65fr;
}

/* At that squeezed-down height the graph panel is too cramped to be useful
   — disable it until the search panel isn't in use anymore. The legend menu
   itself never scrolls (see .pricing-legend-menu), so there's no scrollbar
   timing to worry about here anymore. Same modal-open exception as above. */
.prices-content:has(.prices-search-panel:hover) .prices-graph-panel,
.prices-content:has(.prices-search-panel:focus-within) .prices-graph-panel,
.prices-page:has(#watchlist-add-modal:not(.hidden)) .prices-content .prices-graph-panel {
    pointer-events: none;
    opacity: 0.4;
}

/* Shared .panel (components.css) as a flex column. */
.prices-panel {
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.prices-watchlist-panel {
    grid-area: watchlist;
    padding: 18px 22px;
}

.prices-graph-panel {
    grid-area: graph;
    padding: 18px 22px;
    /* Matches .prices-content's grid-template-rows timing so the fade and
       the resize always finish together, including when interrupted. */
    transition: opacity 0.18s ease-out;
}

.prices-search-panel {
    grid-area: search;
    padding: 18px 22px;
}

.prices-panel-header {
    flex-shrink: 0;
    margin-bottom: 12px;
}

/* .prices-panel-title is the shared .label .label--muted (main.css). */

/* ── Watchlist grid ── */
.prices-watchlist-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

.prices-watchlist-grid {
    flex: 1;
    overflow-y: auto;
    scrollbar-gutter: stable;
    margin-top: 12px;
    display: grid;
    /* auto-fill, not auto-fit — auto-fit collapses any track with no items
       in ANY row, which sizes the grid's own content box down to only
       however many tracks are actually in use before justify-content:center
       centers that. That's fine for a lone full row, but a lone PARTIAL row
       or one that follows a full row would end up floating in the middle of
       the container instead of starting from the left. auto-fill always
       keeps as many tracks as the container can physically fit — a partial
       row is just items filling the first few of those tracks, left-anchored
       within them like any normal grid row, while justify-content:center
       still centers the constant, container-width track set as a whole
       (visible as a small even margin once the tracks don't divide the
       container width exactly). Both a lone card and a full row read as
       "anchored to the same left edge, with the same small margin" — never
       one card floating alone in the middle. */
    grid-template-columns: repeat(auto-fill, 130px);
    gap: 12px;
    align-content: start;
    justify-content: center;
    /* Room for the selected-tile ring (see .prices-watch-tile-media) to
       paint outside a tile without being clipped by this container's own
       overflow — setting overflow-y here also makes overflow-x compute to
       auto rather than visible, so it clips at these edges too. Top/left/
       right get more since those are the edges a ring is most likely to sit
       flush against; bottom already has some breathing room before the
       scroll boundary. */
    padding: 6px 6px 3px;
}

/* .prices-watchlist-grid scrollbar is the shared .scroll-thin (main.css). */

.prices-watch-tile {
    display: flex;
    flex-direction: column;
    gap: 6px;
}

/* The ring lives on this wrapper, not .edition-tile-wrap itself — that has
   its own overflow:hidden (to clip the image to its rounded corners), which
   would clip an outward box-shadow before it ever reached the grid's edge.
   This wrapper has no overflow set, so the ring paints outward untouched. */
.prices-watch-tile-media {
    border-radius: 8px;
}

/* The shared card-tile radius (tiles.css/cards.css) is 14px, sized for the
   255px Cards-page tiles — at this 130px size that reads as too rounded and
   cuts noticeably into the card art's corners. Scoped overrides here (and
   the matching ones for the search-results tiles below) keep the smaller
   tiles' image, clip, and ring all on the same, less-rounded curve without
   touching the shared rule other pages still rely on. */
.prices-watch-tile.card-tile .edition-tile-wrap {
    border-radius: 8px;
}

.prices-watch-tile.card-tile img {
    border-radius: 8px;
}

.prices-watch-tile.selected .prices-watch-tile-media {
    box-shadow: 0 0 0 2px var(--accent);
}

/* Hover-zoom (on this ring-safe wrapper, not .edition-tile-wrap — see the
   comment above .prices-watch-tile-media) and the remove button's visuals
   both come from tiles.css's shared .tile-hoverable/.tile-zoom/
   .tile-action-btn vocabulary — see renderWatchlist in prices.js. */

.prices-watch-tile-info {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 2px;
    text-align: center;
}

.prices-watch-tile-name {
    font-size: 0.78rem;
    color: var(--text);
    max-width: 100%;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

.prices-change {
    font-size: 0.8rem;
    font-weight: 500;
}

.prices-change--up {
    color: var(--series-sales);
}

.prices-change--down {
    color: var(--error);
}

.prices-change--flat {
    color: var(--text-muted);
}

.prices-empty {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    padding: 60px 0;
    color: var(--text-muted);
    text-align: center;
    /* Spans every column so it isn't squeezed into a single 130px cell. */
    grid-column: 1 / -1;
}

/* ── Graph panel ── */
.prices-graph-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    /* The chart is explicitly sized in JS to fit this exact box (see
       showPriceGraph), so overflow should never happen — hidden here is a
       hard guarantee against a scrollbar ever appearing from a rounding or
       measurement edge case, rather than relying on the sizing being pixel
       perfect every time. */
    overflow: hidden;
    min-height: 0;
    transition: opacity 0.18s ease;
}

/* Toggled in showPriceGraph (prices.js) while swapping to a different
   card's chart, so switching between watchlist cards reads as a crossfade
   instead of an abrupt content swap. */
.prices-graph-body.switching {
    opacity: 0;
}

.prices-graph-placeholder,
.prices-graph-empty {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 10px;
    color: var(--text-muted);
    text-align: center;
    padding: 20px;
}

.prices-graph-loading {
    flex: 1;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--text-muted);
    font-family: var(--font-mono);
    font-size: 0.8rem;
}

/* Chart + legend-as-toggle-menu side by side, replacing the legend-above-chart
   stack the drawer's own compact chart still uses. */
.pricing-chart-row {
    display: flex;
    flex-direction: row;
    flex: 1;
    min-height: 0;
    gap: 12px;
}

.pricing-chart-canvas {
    flex: 1;
    min-width: 0;
    min-height: 0;
}

/* Only present when buildPricingComboChart (drawer.js) widens the chart past
   the panel's own width to keep points from crowding together — the SVG
   inside is sized explicitly wider than this wrapper, which clips it down to
   the panel and lets the excess be reached by scrolling. showPriceGraph
   (prices.js) scrolls this to its right edge right after render, so the most
   recent data is what's in view by default. */
.pricing-chart-scroll {
    width: 100%;
    height: 100%;
    overflow-x: auto;
    overflow-y: hidden;
}

.pricing-chart-scroll::-webkit-scrollbar {
    height: 8px;
}

.pricing-chart-scroll::-webkit-scrollbar-track {
    background: var(--bg);
}

.pricing-chart-scroll::-webkit-scrollbar-thumb {
    background: var(--border);
    border-radius: 8px;
}

.pricing-chart-scroll::-webkit-scrollbar-thumb:hover {
    background: var(--border-focus);
}

/* Static — never scrolls, even if there are more toggles than fit. Avoids
   a scrollbar ever needing to appear/disappear as the graph panel resizes
   (see .prices-content's grid-template-rows) while the search panel is in
   use, at the cost of clipping extra toggles in the rare case a card has
   enough sale/listing series to overflow this height. */
.pricing-legend-menu {
    flex-shrink: 0;
    width: 130px;
    display: flex;
    flex-direction: column;
    overflow-y: hidden;
    padding-left: 12px;
    border-left: 1px solid var(--border);
}

/* Splits the menu into two equal-height halves so the Listings group's top
   edge always lands at the same spot — the container's exact midpoint —
   instead of drifting down depending on how many Sales conditions are above
   it (see hasBothGroups in buildPricingComboChart). Only applied when both
   groups actually have something in them; a card with just one type fills
   the whole area normally instead of leaving the other half blank. */
.pricing-legend-menu.has-both {
    display: grid;
    grid-template-rows: 1fr 1fr;
}

.pricing-legend-menu-group {
    display: flex;
    flex-direction: column;
    gap: 8px;
    overflow: hidden;
}

.pricing-legend-menu.has-both .pricing-legend-menu-group:last-child {
    border-top: 1px solid var(--border);
    padding-top: 8px;
}

.pricing-legend-toggle {
    display: flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    color: var(--text-muted);
    transition: opacity 0.15s;
}

.pricing-legend-toggle:hover {
    color: var(--text);
}

.pricing-legend-toggle.off {
    opacity: 0.35;
}

/* Styled as a checkbox — a colored outline box that gets a smaller filled
   square inside it when the series is showing, and stays empty when toggled
   off — so it reads as an on/off control rather than just a color key. The
   color itself comes in via --swatch-color (set inline per series in
   buildLegendMenuGroup) since it's per-series data, not something CSS knows. */
.pricing-legend-swatch {
    position: relative;
    width: 12px;
    height: 12px;
    border-radius: 3px;
    flex-shrink: 0;
    border: 1.5px solid var(--swatch-color);
    transition: border-color 0.15s;
}

/* The "checked" mark — a smaller square centered inside the outline via a
   fixed negative margin (half its own width/height), so it's exactly
   centered regardless of the outer box's border width. */
.pricing-legend-swatch::after {
    content: '';
    position: absolute;
    left: 50%;
    top: 50%;
    width: 6px;
    height: 6px;
    margin: -3px 0 0 -3px;
    border-radius: 1px;
    background: var(--swatch-color);
    transition: opacity 0.15s;
}

.pricing-legend-toggle.off .pricing-legend-swatch::after {
    opacity: 0;
}

.pricing-legend-toggle-label {
    overflow-wrap: break-word;
    word-break: break-word;
}

/* Labels a group of toggles below it "Sales"/"Listings" (see
   buildLegendMenuGroup in drawer.js) so the individual toggle labels can
   just be the condition (e.g. "Near Mint") instead of repeating the type. */
.pricing-legend-menu-header {
    font-family: var(--font-mono);
    font-size: 0.62rem;
    letter-spacing: 0.08em;
    text-transform: uppercase;
    color: var(--text-muted);
    opacity: 0.7;
    flex-shrink: 0;
}

.prices-graph-title {
    font-size: 0.95rem;
    font-weight: 500;
    color: var(--text);
}

.prices-graph-meta {
    font-family: var(--font-mono);
    font-size: 0.72rem;
    color: var(--text-muted);
    margin-top: 2px;
}

/* ── Search panel ── */
.prices-search-body {
    flex: 1;
    display: flex;
    flex-direction: column;
    overflow: hidden;
    min-height: 0;
}

/* Smaller than the Cards page's tile grid (.card-grid uses 255px) — this
   panel is often the width of one grid column, and now that a single search
   can return every printing of a card (see all_prints), a bigger, denser
   grid keeps them from spilling into a tall scroll. */
.prices-search-results {
    flex: 1;
    overflow-y: auto;
    /* Reserves the scrollbar's gutter whether or not it's actually needed,
       so a scrollbar appearing/disappearing as this panel's row resizes
       never changes the available width — which would otherwise reflow
       the grid columns and make the tiles visibly rescale/rewrap mid-resize
       instead of just revealing more already-laid-out rows. */
    scrollbar-gutter: stable;
    margin-top: 12px;
    display: grid;
    /* auto-fill, not auto-fit — same reasoning as the watchlist grid: fit
       collapses any track with no items in ANY row, shrinking the grid's own
       content box to only however many tracks are in use before
       justify-content:center centers that — fine for a full row, but a
       partial or lone row would float in the middle instead of starting
       from the left. auto-fill always keeps as many tracks as the container
       can fit, so a partial row is just items left-anchored within the
       first few of that constant track set, while justify-content:center
       still centers the set as a whole (a small even margin when the
       container width doesn't divide evenly) — full or partial, first row
       or last, everything anchors to the same left edge. */
    grid-template-columns: repeat(auto-fill, 130px);
    gap: 12px;
    align-content: start;
    justify-content: center;
    /* Room for the tile hover-zoom (.card-tile--authed:hover scales
       .edition-tile-wrap up 3%) to grow outward without being clipped by
       this container's own overflow — most noticeable on the first row,
       which has no row above it to borrow clearance from. Same top/left/
       right-biased padding as the watchlist and drawer edition grids. */
    padding: 6px 6px 3px;
}

/* .prices-search-results scrollbar is the shared .scroll-thin (main.css). */

/* Same reasoning as .prices-watch-tile above: less rounded than the shared
   14px card-tile default, which was sized for the larger 255px Cards-page
   tiles and looks too rounded at this panel's 130px size. */
.prices-search-results .card-tile.card-tile--authed .edition-tile-wrap {
    border-radius: 8px;
}

.prices-search-results .card-tile img {
    border-radius: 8px;
}

/* Wraps .edition-tile-wrap so the selected-ring below has somewhere to paint
   that isn't clipped by that element's own overflow:hidden — same reasoning
   as .prices-watch-tile-media above. */
.prices-search-tile-media {
    border-radius: 8px;
}

/* Same ring treatment as .prices-watch-tile.selected — shows which search
   result (if any) is the one currently driving the graph (see
   highlightSelectedPriceCard in prices.js). */
.prices-search-results .card-tile.selected .prices-search-tile-media {
    box-shadow: 0 0 0 2px var(--accent);
}

/* Hover-zoom (on this ring-safe wrapper, not .edition-tile-wrap — see the
   comment above .prices-search-tile-media) comes from tiles.css's shared
   .tile-hoverable/.tile-zoom vocabulary — see buildPriceSearchTile in
   prices.js. */

/* Distinguishes same-card tiles now that search returns every printing
   instead of one randomly chosen edition. */
.prices-tile-caption {
    margin-top: 6px;
    font-family: var(--font-mono);
    font-size: 0.68rem;
    color: var(--text-muted);
    text-align: center;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* "+" button visuals come from tiles.css's shared .tile-action-btn — see
   attachPriceSearchAddOverlay in prices.js. */
