/* ===========================================================================
   dualbar.css - the one bar the numbers get, on every page.

   Visits, favorites and the year a world came out are hard numbers, so they
   get a bar instead of a word to click: one track, two handles, the left one
   the least you will take, the right one the most. Both all the way out means
   "any", and an untouched bar costs nothing. Words stay words - a bar for
   something soft like "cosy" would be a lie.

   The look is Starmap's, and there is exactly one of it: a cut hexagon rail,
   the part already handed over drawn as a lit edge inside it, and the handle
   is the very sigil a held star wears (holdhex.js). Nothing has to be held
   here - the ring simply fills as the handle is turned to the right, and the
   lit part of the rail creeps along under it, so the shape says the number the
   read-out says. The native range input still does all the work and keeps its
   keyboard arrows; only its round track and round knob have gone invisible.

   dualbar.js dresses a bar: it lays out the sigils and keeps --p0/--p1 (0..1)
   and the lit edge in step with the inputs. The knob travel and the lit edge
   share one span - the width less 34px, 8px of slant at each end plus the
   18px sigil - so the light always ends exactly where the handle stands. A bar
   with a single handle is this same bar with its left handle parked at 0.

   Loaded by bibliothek, atlas and the star map, and by nothing else: it needs
   the --hx-* hexagon vars for the lit edge, which only those pages carry.
   =========================================================================== */

/* the read-out over a bar: what the number is, on the left; what it is set
   to, on the right */
.num-h { display: flex; align-items: baseline; justify-content: space-between;
  gap: 8px; margin: 11px 2px 2px; font-size: 10.5px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--ink-faint, #8a86a8); }
.num-h > span { flex: 0 0 auto; }
.num-h b { font-weight: 400; font-size: 11px; letter-spacing: 0;
  text-transform: none; color: var(--ink-soft, #b9b4d6); white-space: nowrap;
  font-variant-numeric: tabular-nums; }

/* the bar itself: room for a 20px rail and nothing that listens underneath.
   --p0 and --p1 are the two handles as fractions of the bar, 0..1 */
.dual { position: relative; height: 20px; margin: 0 0 2px; --p0: 0; --p1: 1; }
.dual .dtr {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
  --ch: 8px;
  background: linear-gradient(180deg, rgba(20, 15, 40, .95), rgba(8, 7, 20, .98));
  clip-path: polygon(
    var(--ch) 0,
    calc(100% - var(--ch)) 0,
    100% 50%,
    calc(100% - var(--ch)) 100%,
    var(--ch) 100%,
    0 50%);
}
/* the rail's own edge, drawn as a 1.2px rim so the dark shape reads as a
   window and not as a hole */
.dual .dtr::after {
  content: ""; position: absolute; inset: 0; z-index: 2; padding: 1.2px;
  background: var(--hx-edge, linear-gradient(90deg, var(--hx-light, #ffb8f4),
    var(--hx-main, #c46bff) 48%, var(--hx-deep, #7a34ff)));
  clip-path: polygon(
    var(--ch) 0,
    calc(100% - var(--ch)) 0,
    100% 50%,
    calc(100% - var(--ch)) 100%,
    var(--ch) 100%,
    0 50%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  mask-composite: exclude;
}
/* what the bar has already handed over: from the left handle to the right one */
.dual .dfill {
  position: absolute; top: 50%; height: 8px; transform: translateY(-50%);
  left: calc(8px + var(--p0, 0) * (100% - 34px));
  width: calc((var(--p1, 1) - var(--p0, 0)) * (100% - 34px));
  background: linear-gradient(90deg, var(--hx-deep, #7a34ff),
    var(--hx-main, #c46bff) 55%, var(--hx-light, #ffb8f4));
  box-shadow: 0 0 9px var(--hx-halo, rgba(196, 107, 255, .42));
}
/* where a handle stands: the sigil, sized 18px so the whole hexagon stays
   clear of the slanted ends. Nothing here listens - the thumb underneath does */
.dual .dknob {
  position: absolute; z-index: 3; top: 50%; width: 18px; height: 18px;
  transform: translateY(-50%); pointer-events: none;
  filter: drop-shadow(0 0 8px var(--hx-halo, rgba(196, 107, 255, .42)));
}
.dual .dknob.k0 { left: calc(8px + var(--p0, 0) * (100% - 34px)); }
.dual .dknob.k1 { left: calc(8px + var(--p1, 1) * (100% - 34px)); }
.dual .dknob .hold-hex { position: absolute; inset: 0; width: 100%; height: 100%; }

/* Two handles are two range inputs lying on top of each other, and the input
   takes no clicks - only its thumb does. That is what lets one track carry two
   handles without a line of dragging code of our own. Keeping the thumb
   invisible rather than taking it away is what keeps the keyboard working. */
.dual input[type=range] {
  -webkit-appearance: none; appearance: none;
  position: absolute; top: 0; left: 0; z-index: 2;
  width: 100%; height: 20px; margin: 0; padding: 0;
  background: none; pointer-events: none; accent-color: var(--accent, #8f7bff);
}
.dual input[type=range]::-webkit-slider-runnable-track {
  background: none; border: 0; height: 20px;
}
/* The box the pointer is given is as wide as the sigil plus one slant of the
   bar at each side (8 + 18 + 8 = 34px), because that is the span the sigil
   itself walks along: the browser centres its thumb on
   17px + p*(width - 34px), which is the very middle of the hexagon for every
   value. A thumb only as wide as the hexagon would be held 10px to the left of
   the thing it drags - the handle would have to be caught beside its own sigil.
   As tall as the rail, too, so it can be caught above and below the line. */
.dual input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  pointer-events: auto; width: 34px; height: 20px; margin-top: 0;
  opacity: 0; background: transparent; border: 0; box-shadow: none;
  cursor: grab;
}
.dual input[type=range]::-webkit-slider-thumb:active { cursor: grabbing; }
.dual input[type=range]::-moz-range-track {
  background: none; border: 0; height: 20px;
}
.dual input[type=range]::-moz-range-thumb {
  pointer-events: auto; width: 34px; height: 20px;
  opacity: 0; background: transparent; border: 0; box-shadow: none;
  cursor: grab;
}
/* the focus ring goes on the sigil-holding bar, not on the invisible thumb */
.dual input[type=range]:focus { outline: none; }
.dual:has(input[type=range]:focus-visible) .dknob {
  filter: drop-shadow(0 0 10px var(--hx-halo, rgba(196, 107, 255, .42)))
    drop-shadow(0 0 0 3px rgba(143, 123, 255, .25));
}
/* A handle standing at the far left has handed nothing over yet, so the ring it
   wears is empty. Left as a faint outline it sinks into the dark rail and the
   bar looks like it has lost its handle. Standing there it is lit for itself
   instead: the outline is drawn as bright and as thick as the lit ring it would
   otherwise wear, so the handle keeps its weight, and a halo holds it off the
   rail. The dock and the corner bars wear the same wake-up (star.css). */
.dual .dknob.blank .hold-hex .hx-track { stroke-opacity: 1; stroke-width: 5.5; }
.dual .dknob.blank .hold-hex .hx-star { stroke-opacity: 1; stroke-width: 2.6; }
.dual .dknob.blank .hold-hex {
  filter: drop-shadow(0 0 4px var(--hx-halo, rgba(196, 107, 255, .55)))
    drop-shadow(0 0 10px var(--hx-halo, rgba(196, 107, 255, .35)));
}
