/* ===========================================================================
   star.css - the Starmap tab. Placement only.
   Every colour and every number comes from theme.css.
   =========================================================================== */

#sky {
  position: fixed; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  display: block; touch-action: none;
}

/* the pages that scroll (Atlas, Library) have to keep clear of the top bar */
.wrap { padding-top: calc(var(--bar-h) + 18px); }

/* the three page templates share the same bar height, so switching a tab
   never moves the tabs themselves */
body.tab-discover { overflow: hidden; }
body.tab-atlas, body.tab-library { overflow-y: auto; }

/* The world count sits in the star field, just below the shared top bar. */
.skycount {
  position: fixed;
  top: calc(var(--bar-h) + 12px);
  left: 50%;
  z-index: 4;
  display: inline-flex;
  align-items: baseline;
  gap: 6px;
  padding: 5px 14px;
  transform: translateX(-50%);
  border: 1px solid var(--hair);
  background: color-mix(in srgb, var(--popup) 84%, var(--panel-soft));
  clip-path: polygon(10px 0, calc(100% - 10px) 0, 100% 50%, calc(100% - 10px) 100%, 10px 100%, 0 50%);
  color: var(--ink-faint);
  font-size: 11.5px;
  letter-spacing: .04em;
  white-space: nowrap;
  pointer-events: none;
}
.skycount b {
  color: var(--ink);
  font-size: 14px;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
}
@media (max-width: 600px) {
  .skycount { top: calc(var(--bar-h) + 8px); padding: 4px 11px; font-size: 11px; }
  .skycount b { font-size: 13px; }
}
/* A zero-match search is an actionable empty state, not just a small number. */
#found.no-results {
  --hx-edge: #ff526e;
  color: #ffe4e8;
  background: rgba(74, 8, 25, .96);
  box-shadow: 0 0 18px rgba(255, 62, 101, .22);
}

/* ===========================================================================
   Holding a star: the very same purple hexagon the atlas draws over a picture
   (its inside is holdhex.css). The layer is one fixed sheet over the sky; the
   hexagon inside it is moved and sized to sit exactly on the star being held,
   so it does not care where on the map that star happens to be.
   =========================================================================== */
#hold-layer { position: fixed; inset: 0; z-index: 18; pointer-events: none; }
#hold-layer .hold-hex {
  position: absolute; aspect-ratio: 1 / 1; pointer-events: none;
  opacity: 0; transform: translate(-50%, -50%) scale(.86);
  transition: opacity .16s ease, transform .22s cubic-bezier(.2, .9, .3, 1.3);
  filter: drop-shadow(0 0 16px rgba(150, 60, 255, .5));
}
#hold-layer .hold-hex.on { opacity: 1; transform: translate(-50%, -50%) scale(1); }
#hold-layer .hold-hex.gone { opacity: 0; transform: translate(-50%, -50%) scale(.9);
  transition-duration: .24s; }

/* while the ring is closing the whole sky steps back, so the sigil is the
   only thing talking */
body.holding #sky { filter: brightness(.5) saturate(.6); transition: filter .25s ease; }

/* what just happened, said out loud at the bottom of the sky */
#star-note {
  position: fixed; left: 50%; bottom: 24px; transform: translateX(-50%);
  z-index: 35; max-width: min(620px, 86vw);
  padding: 11px 18px; border-radius: 12px; text-align: center;
  background: rgba(18, 10, 34, .93); color: #f2e9ff;
  border: 1px solid rgba(160, 90, 255, .45);
  font-size: 14px; line-height: 1.45;
  box-shadow: 0 10px 34px rgba(0, 0, 0, .5);
  pointer-events: none;
}
#star-note.good { border-color: rgba(120, 255, 200, .5); color: #e6fff4; }
#star-note.bad { border-color: rgba(255, 120, 150, .55); color: #ffe9ef; }
#star-note[hidden] { display: none; }


/* ===========================================================================
   The foot of the page: one genre strip above the four numeric filters and the
   centred Reach/Zoom dock. Published and Worlds flank the dock on the left;
   Visits and Favorites flank it on the right.
   =========================================================================== */
.bottom-controls {
  position: fixed; left: 50%; bottom: 14px; transform: translateX(-50%);
  z-index: 34; display: flex; flex-direction: column; align-items: center; gap: 7px;
  width: min(1440px, calc(100vw - 24px)); pointer-events: none;
}
.genre-filters {
  display: flex; flex-direction: row; flex-wrap: nowrap; gap: 4px; min-width: 0; width: 100%;
  overflow-x: auto; overflow-y: hidden; overscroll-behavior-x: contain;
  padding: 4px; pointer-events: auto; scrollbar-width: thin;
}
.genre-filter {
  display: flex; flex: 0 0 auto; align-items: center; gap: 7px; min-width: 0;
  max-width: 180px; padding: 5px 9px; border: 1px solid var(--hair);
  color: var(--ink-soft); background: rgba(8, 7, 20, .84);
  font: inherit; font-size: 11px; line-height: 1.2; text-align: left; cursor: pointer;
  opacity: .62;
}
.genre-filter[data-state="include"] { opacity: 1; border-color: var(--accent); color: var(--ink); }
.genre-filter[data-state="exclude"] {
  opacity: 1; border-color: #ff5369; color: #ff8291;
  background: rgba(82, 13, 30, .88); box-shadow: inset 0 0 0 1px rgba(255, 83, 105, .18);
}
.genre-filter:focus-visible { outline: 2px solid var(--accent-lit, #ff6aa8); outline-offset: 2px; }
.genre-filter i { flex: 0 0 8px; width: 8px; height: 8px; background: currentColor; box-shadow: 0 0 8px currentColor; }
.genre-filter span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.genre-filter .n { margin-left: auto; opacity: .7; font-variant-numeric: tabular-nums; }
.dock {
  grid-area: dock;
  position: relative; left: auto; bottom: auto; transform: none;
  z-index: auto; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: center; gap: 8px;
  pointer-events: auto;
  width: min(410px, calc(100vw - 24px)); max-width: calc(100vw - 24px);
  padding: 8px 14px;
  color: var(--ink); font-size: 12px; letter-spacing: .02em; user-select: none;
}
.dock, .starmap-filter-panel {
  border-radius: 14px;
  background: rgba(18, 10, 34, .82); border: 1px solid var(--hair);
  box-shadow: 0 10px 30px rgba(0, 0, 0, .45);
  backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px);
}
.starmap-filter-layout {
  display: grid; grid-template-columns: minmax(0, 1fr) max-content minmax(0, 1fr);
  grid-template-areas: "left dock right";
  align-items: stretch; gap: 10px; min-width: 0; width: 100%; pointer-events: none;
}
.starmap-filter-panel {
  position: relative;
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); align-content: center;
  align-items: center; gap: 4px 12px; min-width: 0; padding: 8px 12px;
  color: var(--ink); font-size: 12px; letter-spacing: .02em; user-select: none;
  pointer-events: auto;
}
.starmap-filter-panel > * { position: relative; z-index: 1; }
#filter-panel-left { grid-area: left; }
#filter-panel-right { grid-area: right; }
.starmap-filter-panel .dk {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto 20px;
  align-items: center; gap: 2px 5px; min-width: 0;
}
.starmap-filter-panel .dk-lab {
  grid-column: 1; grid-row: 1; min-width: 0; text-align: left;
  opacity: .62; text-transform: uppercase; font-size: 10.5px; letter-spacing: .1em;
}
.starmap-filter-panel .dk-val {
  grid-column: 2; grid-row: 1; min-width: 0; white-space: nowrap; text-align: right; font-weight: 600;
  font-size: 10px; line-height: 14px; letter-spacing: .02em; color: var(--ink);
  opacity: .9; font-variant-numeric: tabular-nums;
}
.starmap-filter-panel .dk-bar,
.starmap-filter-panel .dk-slot {
  grid-column: 1 / -1; grid-row: 2; position: relative; display: block; width: 100%; min-width: 0; height: 20px; margin: 0;
}
.starmap-filter-panel .dk-bar .dual { width: 100%; margin: 0; }
.dock .dk { display: flex; align-items: center; gap: 10px; }
/* Reach is the Zoom control's twin: label/value above a full-width hex rail.
   AKDual's source order is label/read-out then rail, so the header goes
   transparent here and its pieces become the first-row grid items. */
.dock .search-reach {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto 20px;
  align-items: center; gap: 2px 5px;
  width: auto; min-width: 0; padding: 0;
}
.dock .search-reach::before { display: none; }
.dock .search-reach .num-h { display: contents; margin: 0; }
.dock .search-reach .num-h > span {
  grid-column: 1; grid-row: 1; min-width: 0;
  opacity: .62; text-transform: uppercase; font-size: 10.5px; letter-spacing: .1em;
  text-align: left;
}
.dock .search-reach .dual { grid-column: 1 / -1; grid-row: 2; width: 100%; min-width: 0; margin: 0; }
.dock .search-reach .num-h > b { grid-column: 2; grid-row: 1; min-width: 0; }
.dock .dk-lab {
  opacity: .62; text-transform: uppercase; font-size: 10.5px; letter-spacing: .1em;
  min-width: 0; text-align: left;
}
.dock .dk { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto 20px; gap: 2px 5px; }
.dock .dk-lab { grid-column: 1; grid-row: 1; }
.dock .dk-val { grid-column: 2; grid-row: 1; }
.dock .dk-slot { grid-column: 1 / -1; grid-row: 2; width: 100%; }
.dock .dk-val,
.dock .search-reach .num-h > b {
  min-width: 0; white-space: nowrap; text-align: right; font-weight: 600;
  font-size: 10px; line-height: 14px; letter-spacing: .02em; color: var(--ink);
  opacity: .9; font-variant-numeric: tabular-nums;
}

/* ===========================================================================
   The visit-size mode sigil: centred just above the Starmap controls.
   =========================================================================== */
.ctl {
  position: fixed; z-index: 36; top: auto; left: 50%; bottom: calc(var(--dock-h) + 22px);
  transform: translateX(-50%); width: max-content; user-select: none;
}
.ctl-sig {
  position: relative; display: block; width: 44px; height: 44px; margin: 0;
  padding: 0; cursor: pointer;
  border: 1px solid var(--hair); border-radius: 12px;
  background: rgba(18, 10, 34, .82);
  box-shadow: 0 8px 22px rgba(0, 0, 0, .45);
  backdrop-filter: blur(9px); -webkit-backdrop-filter: blur(9px);
  transition: border-color .18s ease, box-shadow .18s ease, background .18s ease;
}
.ctl-sig .hold-hex { position: absolute; inset: 7px; }
.ctl-sig:hover { border-color: var(--accent); }
.ctl-sig[aria-pressed="true"] {
  border-color: var(--accent);
  background: rgba(67, 39, 112, .92);
  box-shadow: 0 0 0 2px rgba(169, 156, 255, .24), 0 0 24px rgba(169, 156, 255, .46);
}
.ctl-sig:focus-visible { outline: none; box-shadow: 0 0 0 3px rgba(143, 123, 255, .35); }
@media (prefers-reduced-motion: reduce) {
  .ctl-sig { transition: none; }
}
/* dock sliders fill the width their parent control actually has */
.dock .dk-bar { position: relative; display: inline-block; width: 100%; min-width: 0; height: 20px; }
.dock .dk-bar .dual { width: 100%; margin: 0; }
.dock input[type=range] {
  -webkit-appearance: none; appearance: none; background: none;
  width: 168px; height: 18px; margin: 0; padding: 0; cursor: pointer;
}
.dock input[type=range]::-webkit-slider-runnable-track {
  height: 4px; border-radius: 99px; border: 1px solid var(--hair);
  background: linear-gradient(90deg, var(--accent), rgba(143, 123, 255, .22));
}
.dock input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 13px; height: 13px; margin-top: -5.5px; border-radius: 50%;
  background: #f2ecff; border: 1px solid var(--accent);
  box-shadow: 0 0 10px rgba(143, 123, 255, .7);
}
.dock input[type=range]::-moz-range-track {
  height: 4px; border-radius: 99px; border: 1px solid var(--hair);
  background: linear-gradient(90deg, var(--accent), rgba(143, 123, 255, .22));
}
.dock input[type=range]::-moz-range-thumb {
  width: 13px; height: 13px; border-radius: 50%;
  background: #f2ecff; border: 1px solid var(--accent);
  box-shadow: 0 0 10px rgba(143, 123, 255, .7);
}
.dock input[type=range]:focus { outline: none; }
/* a handle with nothing left to choose - the three bars have filtered every
   world away - stops answering, so it cannot be dragged into a range it cannot
   hold; it wakes up on its own as soon as worlds come back */
.dock input[type=range]:disabled, .starmap-filter-panel input[type=range]:disabled, .ctl input[type=range]:disabled { opacity: .4; cursor: default; }
.dock input[type=range]:focus-visible::-webkit-slider-thumb,
.starmap-filter-panel input[type=range]:focus-visible::-webkit-slider-thumb {
  box-shadow: 0 0 0 3px rgba(143, 123, 255, .3), 0 0 10px rgba(143, 123, 255, .7);
}
/* a window too narrow for the world: the dock keeps its one handle, so all it
   needs down here is a little less room to stand in, and the panel must never
   reach past the edge of the sky */
@media (max-width: 920px) {
  .bottom-controls { bottom: 8px; width: calc(100vw - 16px); gap: 6px; }
  .starmap-filter-panel { display: flex; flex-direction: column; justify-content: center; align-items: stretch; }
  .dock { display: flex; flex-direction: column; align-items: stretch; gap: 7px; width: 100%; padding: 9px 18px 10px; }
  .dock .dk { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto 20px; align-items: center; gap: 2px 5px; min-width: 0; }
  .dock .dk-lab { grid-column: 1; grid-row: 1; min-width: 0; text-align: left; }
  .dock .dk-val, .dock .search-reach .num-h > b { grid-column: 2; grid-row: 1; min-width: 0; font-size: 10px; line-height: 14px; }
  .dock .search-reach { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto 20px; align-items: center; gap: 2px 5px; width: 100%; min-width: 0; }
  .dock .search-reach .num-h > span { grid-column: 1; grid-row: 1; min-width: 0; text-align: left; }
  .dock .search-reach .dual { grid-column: 1 / -1; grid-row: 2; width: 100%; min-width: 0; }
  .dock .dk-slot { grid-column: 1 / -1; grid-row: 2; width: 100%; min-width: 0; }
  .starmap-filter-layout {
    grid-template-columns: 1fr 1fr;
    grid-template-areas: "left right" "dock dock";
    align-items: stretch; gap: 6px;
  }
  .starmap-filter-panel { gap: 7px; padding: 8px; }
  .starmap-filter-panel .dk {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-rows: auto 20px; gap: 2px 6px;
  }
  .starmap-filter-panel .dk-lab { grid-column: 1; grid-row: 1; text-align: left; }
  .starmap-filter-panel .dk-val { grid-column: 2; grid-row: 1; }
  .starmap-filter-panel .dk-bar,
  .starmap-filter-panel .dk-slot { grid-column: 1 / -1; grid-row: 2; }
  .starmap-filter-layout #dock {
    grid-column: 1 / -1; width: 100%; max-width: none; box-sizing: border-box;
  }
}
@media (max-width: 660px) {
  /* the value before star.js measures the dock: compact panels add their actual height at runtime */
  :root { --dock-h: 42px; }
  .dock { padding: 8px 14px 9px; }
  .starmap-filter-panel { padding: 7px; }
}

@media (max-width: 760px) {
  .genre-filters { padding: 2px; }
  .genre-filter { padding: 4px 6px; font-size: 10px; max-width: 145px; }
  .ctl { bottom: calc(var(--dock-h) + 16px); }
}

.ctl-sig[hidden] { display: none; }

/* the note that says what the sky is doing sits above the dock, never under it */
#star-note { bottom: calc(var(--dock-h) + 44px); }

/* ===========================================================================
   the two handles wear the sigil
   ===========================================================================
   Round track, round knob: the last circles in a page made of hexagons. Each
   handle is now a hexagon bar - the elongated shape, a point at each side -
   with the hold-ring riding inside it, the very sigil a star draws over itself
   while the finger stays down. Nothing has to be held here: the ring simply
   fills as the handle is turned to the right, and the lit part of the bar
   creeps along under it, so the shape says the number the read-out says.
   The native control still does the work and keeps its own geometry; only its
   track and knob have gone invisible. */
.dock .dk-slot { position: relative; width: 100%; min-width: 0; height: 20px; }
.starmap-filter-panel .dk-slot { position: relative; width: 100%; height: 20px; }
.ctl .dk-slot { position: relative; height: 20px; }
.dock .dk-slot input[type=range], .starmap-filter-panel .dk-slot input[type=range], .ctl .dk-slot input[type=range] {
  -webkit-appearance: none; appearance: none;
  position: relative; z-index: 2; width: 100%; height: 20px;
  margin: 0; padding: 0; border: 0; background: none;
}
.dock .dk-rail, .starmap-filter-panel .dk-rail, .ctl .dk-rail {
  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%);
}
.dock .dk-rail::after, .starmap-filter-panel .dk-rail::after, .ctl .dk-rail::after {
  content: "";
  position: absolute; inset: 0; z-index: 2;
  padding: 1.2px;
  background: var(--hx-edge);
  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, up to wherever the sigil stands */
.dock .dk-fill, .starmap-filter-panel .dk-fill, .ctl .dk-fill {
  position: absolute; left: 8px; top: 50%; width: 0; height: 8px;
  transform: translateY(-50%);
  background: linear-gradient(90deg, var(--hx-deep), var(--hx-main) 55%, var(--hx-light));
  box-shadow: 0 0 9px var(--hx-halo);
}
/* the sigil itself: the knob that is not a knob, where the value stands.
   It keeps clear of the slanted ends, so the whole hexagon stays in the bar. */
.dock .dk-slot .hold-hex, .starmap-filter-panel .dk-slot .hold-hex, .ctl .dk-slot .hold-hex {
  position: absolute; z-index: 3;
  left: calc(8px + var(--p, 0) * (100% - 34px));
  top: 50%; width: 18px; height: 18px; opacity: 1;
  transform: translateY(-50%);
  filter: drop-shadow(0 0 8px var(--hx-halo));
  pointer-events: none;
}
.dock .dk-slot input[type=range]::-webkit-slider-runnable-track,
.starmap-filter-panel .dk-slot input[type=range]::-webkit-slider-runnable-track,
.ctl .dk-slot input[type=range]::-webkit-slider-runnable-track {
  background: none; border: 0; height: 20px;
}
/* The box the browser gives the pointer has to lie exactly under the sigil
   that can be seen, or the handle is caught somewhere it is not. A thumb as
   wide as the sigil (18px) plus one slant of the bar at each side (8px + 8px)
   is centred by the browser on 17px + p*(width - 34px) - and that is the very
   centre of the hexagon, which walks 8px + 9px + p*(width - 34px). Same for
   every value, so the whole 34px box is the grab area and the hexagon sits in
   the middle of it. As tall as the rail, so a handle can be caught above and
   below the thin line it draws. */
.dock .dk-slot input[type=range]::-webkit-slider-thumb,
.starmap-filter-panel .dk-slot input[type=range]::-webkit-slider-thumb,
.ctl .dk-slot input[type=range]::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: 34px; height: 20px; margin-top: 0; opacity: 0;
  background: transparent; border: 0; box-shadow: none;
}
.dock .dk-slot input[type=range]::-moz-range-track,
.starmap-filter-panel .dk-slot input[type=range]::-moz-range-track,
.ctl .dk-slot input[type=range]::-moz-range-track {
  background: none; border: 0; height: 20px;
}
.dock .dk-slot input[type=range]::-moz-range-thumb,
.starmap-filter-panel .dk-slot input[type=range]::-moz-range-thumb,
.ctl .dk-slot input[type=range]::-moz-range-thumb {
  width: 34px; height: 20px; opacity: 0;
  background: transparent; border: 0; box-shadow: none;
}
/* A handle standing at the far left has handed nothing over, so its ring is
   empty. Left as a faint outline it sinks into the dark rail and the bar looks
   like it has lost its handle altogether. 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 shared bar wears the same wake-up (dualbar.css). */
.dock .dk-slot .hold-hex.blank .hx-track,
.starmap-filter-panel .dk-slot .hold-hex.blank .hx-track,
.ctl .dk-slot .hold-hex.blank .hx-track { stroke-opacity: 1; stroke-width: 5.5; }
.dock .dk-slot .hold-hex.blank .hx-star,
.starmap-filter-panel .dk-slot .hold-hex.blank .hx-star,
.ctl .dk-slot .hold-hex.blank .hx-star { stroke-opacity: 1; stroke-width: 2.6; }
.dock .dk-slot .hold-hex.blank,
.starmap-filter-panel .dk-slot .hold-hex.blank,
.ctl .dk-slot .hold-hex.blank {
  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)));
}

@media (max-width: 420px) {
  .dock { padding-left: 10px; padding-right: 10px; }
}
