/*
 * Dual-handle price range.
 *
 * Two real <input type="range"> stacked on one rail, so both handles are
 * separately focusable and arrow-key operable. Only the thumbs take pointer
 * events; the inputs themselves do not, or the upper one would swallow every
 * click meant for the lower.
 *
 * --lo and --hi are fractions of the ceiling, set by the server for first paint
 * and by selectie.js while dragging.
 */

.price-slider {
    position: relative;
    height: 44px;
    display: flex;
    align-items: center;
}

/* The thumb is a 24px hit area with an 18px disc painted in the middle of it
   (see below). A range input keeps its thumb inside its own box, so at either
   extreme the disc's outer edge sits 3px in from the input's edge - the rail is
   inset by the same 3px, so it ends exactly under the disc rather than poking
   out beyond it. */
.price-slider__rail {
    position: absolute;
    inset-inline: 3px;
    height: 6px;
    border-radius: 3px;
    background: #e4e6f0;
}

/* Runs between the two thumb centres, so its ends stay hidden under the
   handles. It is positioned inside the rail, so 100% here is the rail's width,
   not the input's. Thumb centres start half a 24px box in - 12px from the
   input's edge, which is 9px along the inset rail - and travel the input's width
   less one box, which is the rail's width less 18px. */
.price-slider__fill {
    position: absolute;
    inset-block: 0;
    inset-inline-start: calc(9px + var(--lo) * (100% - 18px));
    inset-inline-end: calc(9px + (1 - var(--hi)) * (100% - 18px));
    border-radius: 3px;
    background: var(--shop-accent);
}

.price-slider__range {
    position: absolute;
    inset-inline: 0;
    width: 100%;
    height: 44px;
    margin: 0;
    padding: 0;
    appearance: none;
    background: none;
    pointer-events: none;
}

/* When both handles hold the same value they are exactly coincident, and the
   later one in the DOM would take every press — leaving the lower handle
   unreachable by pointer. That is the default state, both at the ceiling, so
   the lower handle is raised above the upper one and JS lowers it again as soon
   as they part. */
.price-slider__range--from {
    z-index: 2;
}

.price-slider__range--to {
    z-index: 1;
}

.price-slider.is-split .price-slider__range--from {
    z-index: 1;
}

.price-slider.is-split .price-slider__range--to {
    z-index: 2;
}

.price-slider__range::-webkit-slider-runnable-track {
    height: 44px;
    background: none;
}

.price-slider__range::-moz-range-track {
    height: 44px;
    background: none;
}

/* The handle is 18px of visible purple inside a 24px target: the transparent
   border is part of the control for hit-testing but is not painted, so the
   touch target meets 24x24 without the design changing. */
.price-slider__range::-webkit-slider-thumb {
    appearance: none;
    width: 24px;
    height: 24px;
    border: 3px solid transparent;
    border-radius: 50%;
    background: var(--shop-accent);
    background-clip: content-box;
    box-sizing: border-box;
    cursor: pointer;
    pointer-events: auto;
    /* The track is 44px so the whole strip is grabbable, but Chrome paints the
       thumb at the top of it rather than centred; (44 - 24) / 2 puts the handle
       back on the rail. */
    margin-block-start: 10px;
}

.price-slider__range::-moz-range-thumb {
    width: 24px;
    height: 24px;
    border: 3px solid transparent;
    border-radius: 50%;
    background: var(--shop-accent);
    background-clip: content-box;
    box-sizing: border-box;
    cursor: pointer;
    pointer-events: auto;
}

/* The values under the rail. Not a live region: each range announces its own
   value through aria-valuetext, and announcing it twice per arrow key is worse
   than not announcing it here at all. */
.price-slider-readout {
    display: flex;
    justify-content: space-between;
    gap: var(--shop-space-2);
    color: var(--shop-text-soft);
    font-size: var(--shop-text-md);
    font-variant-numeric: tabular-nums;
}
