/* ── NICHE EXPLORER ────────────────────────────────────
 *
 * Two columns that mean two different things, and they must not be mistaken
 * for each other: the stack on the left is the FUTURE (what has been found
 * but not looked at), the log on the right is the PAST (what was done, and
 * what it turned up). The research database runs full width underneath,
 * because that is the thing you came for.
 *
 * Every colour here is a token, so the light theme costs nothing: the only
 * hard-coded value in the file is the black scrim over a thumbnail, which is
 * a shadow rather than a colour and is wrong in both themes if it flips.
 */

/* ── before a run ─────────────────────────────────────
 *
 * This was a centred column holding a grey skeleton, a paragraph and an
 * empty box. On a workspace with no niche it offered no terms at all, so
 * the only button was disabled and the only advice was to go and configure
 * something else and come back.
 *
 * Now it is two columns: what a run does on the left, drawn as the tree it
 * actually builds, and the two things you have to decide on the right.
 */
/* It sits inside .rs-panel, which already draws the surface and carries the
   run tabs — so the setup screen gets the same navigation as the run it is
   about to become. */
.rs-panel-setup { padding: 0; }
.rs-setup { padding: 22px 20px 24px; }

.rs-su-top { max-width: 620px; margin-bottom: 20px; }
.rs-su-t {
  margin: 0 0 7px;
  font-size: 19px;
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--tx);
}
.rs-su-d { margin: 0; font-size: 13px; line-height: 1.6; color: var(--t4); }

.rs-su-cols {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 420px);
  gap: 34px;
  align-items: start;
}

/* ── left: the thing it is about to build ───────────── */
.rs-su-l {
  padding: 20px 22px 22px;
  background: var(--bg);
  border: 1px solid var(--b1);
  border-radius: var(--r-4);
}

/* A still of a run, in the live tree's own classes so it cannot drift from
   what it is promising. Taller than its nodes need: the bottom node sits
   below the box on purpose, so the branch reads as continuing. */
.rs-tree.preview {
  position: relative;
  height: 236px;
  margin-bottom: 22px;
  overflow: hidden;
  /* It is an illustration, not a control. */
  pointer-events: none;
  user-select: none;
  -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent);
  mask-image: linear-gradient(to bottom, #000 72%, transparent);
}
.rs-tree.preview .rs-tn { font-size: 11.5px; padding: 6px 11px; max-width: 150px; }

.rs-su-h {
  margin-bottom: 12px;
  font-size: 12.5px;
  font-weight: 600;
  color: var(--t2);
}

/* Numbered because it IS a sequence — the fifth step is what turns one seed
   term into a map of the niche, and it only makes sense after the fourth. */
.rs-su-steps {
  counter-reset: rsstep;
  list-style: none;
  margin: 0 0 16px;
  padding: 0;
}
.rs-su-steps li {
  position: relative;
  padding: 6px 0 6px 30px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--t2);
}
.rs-su-steps li::before {
  counter-increment: rsstep;
  content: counter(rsstep);
  position: absolute;
  left: 0; top: 6px;
  width: 20px; height: 20px;
  display: grid; place-items: center;
  font-size: 10.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--t3);
  background: var(--bg3);
  border-radius: 50%;
}

.rs-su-note { margin: 0; font-size: 12.5px; line-height: 1.6; color: var(--t4); }

/* ── right: the two decisions ───────────────────────── */
.rs-su-r {
  padding: 20px 22px 22px;
  background: var(--bg);
  border: 1px solid var(--b1);
  border-radius: var(--r-4);
}

.rs-su-step { margin-bottom: 24px; }
.rs-su-step:last-of-type { margin-bottom: 20px; }

.rs-su-sh {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 11px;
  font-size: 13px;
  font-weight: 600;
  color: var(--tx);
}
.rs-su-sn {
  flex: none;
  width: 19px; height: 19px;
  display: grid; place-items: center;
  font-size: 10.5px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--t3);
  background: var(--bg3);
  border: 1px solid var(--b2);
  border-radius: 50%;
}

/* The niche, set here rather than somewhere else and back. */
.rs-su-picker { display: flex; flex-wrap: wrap; gap: 7px; }
.rs-su-np {
  padding: 7px 13px;
  font: inherit;
  font-size: 12.5px;
  color: var(--t2);
  background: var(--bg3);
  border: 1px solid var(--b1);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease, background .15s ease;
}
.rs-su-np:hover {
  color: var(--accent);
  background: var(--accent-bg);
  border-color: var(--accent-line);
}

.rs-su-niche.set { display: flex; align-items: baseline; gap: 10px; }
.rs-su-nv { font-size: 15px; font-weight: 600; color: var(--tx); }

.rs-su-hint { margin: 0; font-size: 12.5px; line-height: 1.6; color: var(--t4); }

.rs-su-go { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; }
.rs-cost { font-size: 12px; line-height: 1.5; color: var(--t4); }

/* Chips and their input are shared with nothing else now, so they live with
   the screen that owns them. */
.rs-seeds { display: flex; flex-wrap: wrap; gap: 7px; margin-bottom: 10px; }

.rs-seed {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 5px 5px 5px 11px;
  font-size: 13px;
  color: var(--tx);
  background: var(--bg3);
  border: 1px solid var(--b1);
  border-radius: var(--r-pill);
}
.rs-seed-x {
  width: 17px; height: 17px;
  display: grid; place-items: center;
  font-size: 14px; line-height: 1;
  color: var(--t3);
  background: none; border: 0; border-radius: 50%;
  cursor: pointer;
  transition: color .15s ease, background .15s ease;
}
.rs-seed-x:hover { color: var(--tx); background: var(--b2); }

.rs-seed-add input,
.rs-push input {
  width: 100%;
  padding: 7px 12px;
  font: inherit;
  font-size: 13px;
  color: var(--tx);
  background: transparent;
  border: 1px dashed var(--b2);
  border-radius: var(--r-pill);
  outline: none;
  transition: border-color .15s ease;
}

/* The other thing you act on here. It sat flush under the status strip
   looking like part of it. */
.rs-push {
  position: relative;
  margin: 0 -16px -16px;
  padding: 12px 16px 14px;
  background: var(--bg3);
  border-top: 1px solid var(--b1);
}
.rs-push input {
  padding: 9px 14px 9px 34px;
  background: var(--bg2);
  border-style: solid;
  border-color: var(--b2);
}
.rs-push input:hover { border-color: var(--b3); }
/* A + in the gutter, so the field reads as "add" before it is focused. */
.rs-push::before {
  content: '+';
  position: absolute;
  left: 30px; top: 50%;
  margin-top: -9px;
  width: 18px;
  font-size: 15px;
  line-height: 18px;
  text-align: center;
  color: var(--t4);
  pointer-events: none;
}
.rs-seed-add input::placeholder,
.rs-push input::placeholder { color: var(--t4); }
.rs-seed-add input:focus,
.rs-push input:focus { border-color: var(--accent-line); border-style: solid; }

.rs-seedbox-n {
  margin-left: auto;
  padding: 1px 7px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--t3);
  background: var(--bg3);
  border-radius: var(--r-pill);
}

/* ── ONE PANEL ────────────────────────────────────────
 *
 * The controls, the counters, the budget, the tree and the status line were
 * five things in two floating cards with three different paddings. They are
 * one surface now, divided by rules rather than by gaps — which is the
 * difference between a screen and a pile of boxes.
 */
.rs-panel {
  margin-bottom: 26px;
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-5);
  overflow: hidden;
}

/* Past runs, as tabs. Starting a run has always archived the previous one
   rather than deleting it, but nothing ever showed the archived ones — so
   in practice the research WAS gone: in the database, unreachable. */
.rs-runs {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px;
  background: var(--bg3);
  border-bottom: 1px solid var(--b1);
}
.rs-runs-tabs { display: flex; gap: 6px; flex: 1; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.rs-runs-tabs::-webkit-scrollbar { display: none; }

.rs-rt {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  flex: none;
  max-width: 200px;
  padding: 5px 11px;
  font: inherit;
  font-size: 12.5px;
  color: var(--t3);
  background: transparent;
  border: 1px solid transparent;
  border-radius: var(--r-pill);
  cursor: pointer;
  white-space: nowrap;
  transition: color .15s ease, background .15s ease;
}
.rs-rt-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* Setting one up: the tabs are still there to go back to, and the bar says
   why none of them is selected. */
.rs-runs-hint {
  flex: none;
  font-size: 11.5px;
  font-style: italic;
  color: var(--t4);
}
.rs-rt:hover { color: var(--tx); background: var(--bg4); }
.rs-rt.on { color: var(--tx); font-weight: 600; background: var(--bg2); border-color: var(--b2); }

.rs-rt-n {
  flex: none;
  padding: 0 6px;
  font-size: 10.5px;
  font-variant-numeric: tabular-nums;
  color: var(--t4);
  background: var(--b1);
  border-radius: var(--r-pill);
}
.rs-rt.on .rs-rt-n { color: var(--accent); background: var(--accent-bg); }

.rs-rt-new {
  flex: none;
  padding: 5px 11px;
  font: inherit;
  font-size: 12.5px;
  color: var(--t3);
  background: transparent;
  border: 1px dashed var(--b2);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.rs-rt-new:hover { color: var(--accent); border-color: var(--accent-line); }

/* ── the header row ─────────────────────────────────── */
.rs-head {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
  padding: 14px 16px;
  border-bottom: 1px solid var(--b1);
}
.rs-head-l { display: flex; gap: 8px; }

.rs-go {
  min-width: 86px;
  padding: 8px 18px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--accent);
  border: 0;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background .15s ease;
}
.rs-go:hover { background: var(--accent-hi); }

/* Running is a state, not a spinner. The pulse is the only thing on the page
   that moves on its own, so it reads as "this is live" without a progress bar
   pretending to know how long a niche takes. */
.rs-go.on { background: var(--bg4); color: var(--tx); animation: rs-pulse 1.6s ease-in-out infinite; }
@keyframes rs-pulse { 0%, 100% { box-shadow: 0 0 0 0 var(--accent-glow); } 50% { box-shadow: 0 0 0 6px transparent; } }

.rs-step {
  padding: 8px 14px;
  font: inherit;
  font-size: 13px;
  color: var(--t2);
  background: var(--bg3);
  border: 1px solid var(--b1);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.rs-step:hover:not(:disabled) { color: var(--tx); border-color: var(--b3); }
.rs-step:disabled { opacity: .45; cursor: default; }

.rs-stats { display: flex; gap: 22px; margin-left: auto; }
.rs-stat {
  display: flex;
  flex-direction: column;
  gap: 1px;
  font-size: 11.5px;
  color: var(--t3);
}
.rs-stat span {
  font-size: 17px;
  font-weight: 600;
  color: var(--tx);
  font-variant-numeric: tabular-nums;
}

/* The budget is on screen because it is the real limit on this feature: a
   search costs a hundred units of ten thousand a day. Hiding it would mean
   the run simply stops one afternoon with no explanation. */
.rs-budget { width: 132px; }
.rs-budget-t { margin-bottom: 5px; font-size: 11.5px; color: var(--t3); }
.rs-budget-track {
  height: 4px;
  background: var(--bg4);
  border-radius: var(--r-pill);
  overflow: hidden;
}
.rs-budget-track i {
  display: block;
  height: 100%;
  background: var(--accent);
  border-radius: inherit;
  transition: width .3s ease;
}
.rs-budget.out .rs-budget-track i { background: var(--warning); }

.rs-note {
  padding: 11px 16px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--t2);
  background: var(--warning-bg);
  border-bottom: 1px solid var(--b1);
  box-shadow: inset 2px 0 0 var(--warning);
}

/* ── THE LAUNCHER ─────────────────────────────────────
 *
 * Three tools, each described properly and shown doing its own job. They
 * were a compact row pinned above whatever you were working on, which is
 * why every attempt to make them feel like separate features fought with
 * every attempt to keep them out of the way. Opening one takes over the
 * view now, so the choosing screen can be as large as the choice deserves.
 */

/* Each tool owns a hue: identity. The brand accent stays for state. */
.rs-scope, .rs-launch { --tool: var(--accent); --tool-bg: var(--accent-bg); }
.rs-scope[data-tool="rivals"],  .rs-launch[data-tool="rivals"]  { --tool: #3b82f6; --tool-bg: rgba(59, 130, 246, .12); }
.rs-scope[data-tool="remakes"], .rs-launch[data-tool="remakes"] { --tool: #8b5cf6; --tool-bg: rgba(139, 92, 246, .12); }

.rs-launcher {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* A card per tool, wide rather than tall: the illustration needs room to
   be legible, and three stacked rows read as three separate things where
   three narrow columns read as one choice between options. */
.rs-launch {
  display: grid;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  align-items: stretch;
  overflow: hidden;
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-6);
  cursor: pointer;
  transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.rs-launch:hover {
  border-color: var(--b3);
  box-shadow: 0 10px 30px -18px rgba(0, 0, 0, .35);
  transform: translateY(-1px);
}
.rs-launch:focus-visible { outline: 2px solid var(--tool); outline-offset: 3px; }

/* The illustration side. A faint wash of the tool's own hue is what tells
   the three apart before a word is read. */
.rs-launch-art {
  position: relative;
  min-width: 0;
  padding: 26px 26px 0;
  background:
    radial-gradient(120% 90% at 0% 0%, var(--tool-bg), transparent 62%),
    var(--bg);
  border-right: 1px solid var(--b1);
  overflow: hidden;
}
/* The stills are built for a workspace; in a card they sit flush and fade
   out at the bottom edge rather than ending in a box. */
.rs-launch-art .rs-still {
  margin: 0;
  max-width: none;
  border-color: var(--b1);
  box-shadow: 0 12px 28px -20px rgba(0, 0, 0, .4);
}
.rs-launch-art .rs-tree-outer.preview { margin: 0; padding-left: 0; }
.rs-launch-art .rs-lvl-labels { display: none; }

.rs-launch-b {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: 28px 30px;
}

/* Icon and "Start from…" share one line: the hue says which tool it is, the
   label says what you bring to it. */
.rs-launch-top { display: flex; align-items: center; gap: 10px; }
.rs-launch-ic {
  display: grid;
  place-items: center;
  width: 28px; height: 28px;
  color: var(--tool);
  background: var(--tool-bg);
  border-radius: var(--r-2);
}
.rs-launch-ic svg { width: 16px; height: 16px; }

.rs-launch-from {
  font-size: 12px;
  font-weight: 500;
  color: var(--t3);
}

.rs-launch-n {
  margin: 12px 0 6px;
  font-size: 19px;
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: -.015em;
  color: var(--tx);
}

.rs-launch-d {
  margin: 0;
  max-width: 560px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--t3);
}
.rs-launch-d em { color: var(--t2); }
.rs-launch-d .learn-more { margin-left: 4px; color: var(--t2); }
.rs-launch-d .learn-more:hover { color: var(--tool); }

/* Work in progress: a plain line with the tool's dot, not a filled box. */
.rs-launch-note {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-top: 14px;
  font-size: 13px;
  line-height: 1.5;
  color: var(--t2);
}
.rs-launch-note::before {
  content: '';
  flex-shrink: 0;
  width: 6px; height: 6px;
  border-radius: 50%;
  background: var(--tool);
  transform: translateY(-1px);
}
.rs-launch-note strong { color: var(--tx); font-weight: 600; }

.rs-launch-act {
  padding-top: 18px;
}

/* A span, not a button: the whole card is the control, and a nested
   button would be a second target for the same action. Ink, per the brand
   rule — the tool's hue lives in the icon and the illustration. */
.rs-launch-go {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 7px 13px;
  font-size: 13px;
  font-weight: 500;
  color: var(--tx);
  background: var(--bg2);
  border: 1px solid var(--b2);
  border-radius: var(--r-pill);
  transition: gap .18s ease, background .18s ease, color .18s ease, border-color .18s ease;
}
.rs-launch-go svg { width: 12px; height: 12px; }
/* Quiet at rest; the card's hover is what fills it in. */
.rs-launch:hover .rs-launch-go { gap: 9px; color: var(--fill-ink); background: var(--tx); border-color: var(--tx); }

/* ── a tool's own page ─────────────────────────────── */
/* The way back, and the only thing that names which tool you are in now
   the three cards are not sitting above it. */
.rs-crumb {
  display: flex;
  align-items: center;
  gap: 9px;
  margin-bottom: 16px;
  font-size: 13px;
}
.rs-crumb-back {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 5px 11px 5px 9px;
  font: inherit;
  font-size: 12.5px;
  color: var(--t3);
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.rs-crumb-back svg { width: 13px; height: 13px; }
.rs-crumb-back:hover { color: var(--tx); border-color: var(--b3); }
.rs-crumb-sep { color: var(--t5); }
.rs-crumb-ic { display: grid; place-items: center; width: 18px; height: 18px; color: var(--tool); }
.rs-crumb-ic svg { width: 17px; height: 17px; }
.rs-crumb-n { font-weight: 600; color: var(--tx); }
.rs-crumb .learn-more { margin-left: 4px; }

/* The workspace belongs to the tool that owns it — one hairline. */
.rs-scope .rs-panel { border-top: 1px solid var(--tool); }

/* ── THE RUN, AS A TREE ──────────────────────────────
 *
 * What this actually is: a tree, walked depth first, with a stack holding
 * everything found but not yet followed. It was an indented list first,
 * which hinted at the shape without showing it — you could see a row was
 * further in, but not what it came out of.
 *
 * Stack on the left in pop order, tree on the right with the live branch
 * inked and the rest faded back. The two halves are the same fact twice:
 * the stack is a list of the nodes this picture has not reached yet.
 */
.rs-trail { padding: 16px; }

.rs-trail-h {
  display: flex;
  align-items: baseline;
  gap: 10px;
  margin-bottom: 14px;
}
.rs-trail-h .rs-col-h { margin-bottom: 0; }
.rs-trail-m { margin-left: auto; font-size: 11.5px; color: var(--t4); font-variant-numeric: tabular-nums; }

.rs-tree-wrap {
  display: grid;
  grid-template-columns: 158px minmax(0, 1fr);
  gap: 18px;
  align-items: start;
}
/* The level labels live in the tree's own left gutter, so the tree gets
   padding rather than another grid track. */
.rs-tree-wrap > .rs-tree { padding-left: 108px; }

/* ── the stack ──────────────────────────────────────── */
/* The count beside a column heading. It travelled with the old panels and
   lost its rule when they were replaced. */
.rs-col-n {
  padding: 1px 7px;
  font-size: 11px;
  font-variant-numeric: tabular-nums;
  color: var(--t3);
  background: var(--bg3);
  border-radius: var(--r-pill);
}

/* Its own rule only so a long label truncates instead of widening the grid
   track and squeezing the tree. */
.rs-stk-col { min-width: 0; }

.rs-stk-h {
  margin-bottom: 9px;
  font-size: 11px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--t4);
}
.rs-stk { list-style: none; margin: 0; padding: 0; }

.rs-stk-i {
  position: relative;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 5px 4px 5px 0;
  font-size: 12.5px;
  /* It was --t4, which on this background is barely there. The stack is
     half of what this panel is for. */
  color: var(--t3);
}
/* The top of the stack is the node the tree has lit. Nothing else in this
   column is more important than which one is next. */
.rs-stk-i.next { color: var(--tx); font-weight: 600; }

.rs-stk-t { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rs-stk-n {
  flex: none;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--accent);
}
/* A small grey note in the stack column — “+4 more”, or “empty”. One name,
   because they are one thing: an aside about the list, not an empty state. */
.rs-stk-note { padding: 6px 0; font-size: 11.5px; color: var(--t5); }

.rs-item-x {
  flex: none;
  align-self: center;
  width: 19px; height: 19px;
  display: grid; place-items: center;
  font-size: 13px;
  line-height: 1;
  color: var(--t4);
  background: transparent;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  transition: opacity .15s ease, color .15s ease, background .15s ease;
}
.rs-item-x:hover { color: var(--danger); background: var(--danger-bg); }

.rs-stk-i .rs-item-x { opacity: 0; }
.rs-stk-i:hover .rs-item-x { opacity: 1; }
@media (hover: none) { .rs-stk-i .rs-item-x { opacity: 1; } }

/* ── THE TREE ─────────────────────────────────────────
 *
 * The layout used to be `x = (i + 0.5) * slot` — every row spread across
 * the full width INDEPENDENTLY, so the live node landed wherever its index
 * happened to fall: root at 50%, its live child at 16%, that one's child at
 * 52%. The trunk zigzagged, and the curves had to cross most of the panel
 * to connect, which is why they bulged past their targets and crossed.
 *
 * One rule fixes it: the live node of every row sits at 50% and its
 * siblings fan out around it, nearest first, alternating sides. The trunk
 * is a straight line down the middle, every edge is a short symmetric fan
 * from the node directly above, and nothing can cross.
 */
/* The labels live outside the scroller: they say which level a row is, and
   a level does not move when you pan sideways. */
.rs-tree-outer { position: relative; padding-left: 104px; }

.rs-lvl-labels { position: absolute; inset: 0 auto 0 0; width: 96px; pointer-events: none; }

/* A row wider than the panel pans rather than squeezing. Expanding should
   reveal more, not compress what is already there. */
.rs-tree {
  position: relative;
  min-height: 96px;
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
  /* The edges of the canvas fade rather than cutting a pill in half, so
     there is somewhere obviously still to go. */
  -webkit-mask-image: linear-gradient(to right, transparent, #000 18px, #000 calc(100% - 18px), transparent);
  mask-image: linear-gradient(to right, transparent, #000 18px, #000 calc(100% - 18px), transparent);
}
.rs-tree::-webkit-scrollbar { height: 6px; }
.rs-tree::-webkit-scrollbar-thumb { background: var(--b2); border-radius: var(--r-pill); }
.rs-tree::-webkit-scrollbar-track { background: transparent; }

.rs-canvas { position: relative; min-width: 100%; }

.rs-tree-edges {
  position: absolute;
  inset: 0;
  overflow: visible;
  pointer-events: none;
}
.rs-tree-edges path { fill: none; stroke: var(--b2); stroke-width: 1.4; }
/* The branch being worked is the only one drawn at full strength, which is
   what makes a glance at this answer "where is it". */
.rs-tree-edges path.live { stroke: var(--accent); stroke-width: 1.8; }

/* What this level IS, in the gutter. Costs no space in the tree itself and
   is the difference between a diagram you read and one you decode. */
.rs-lvl-l {
  position: absolute;
  left: 0;
  width: 96px;
  font-size: 10.5px;
  line-height: 1.35;
  text-align: right;
  color: var(--t5);
}

/* A node is centred on its own x, so a long label grows both ways instead
   of pushing the tree sideways. */
.rs-tn {
  position: absolute;
  transform: translateX(-50%);
  z-index: 1;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  /* One pitch less a gutter. Wider than this and neighbours touch; the
     layout hands out 196px per node. */
  max-width: 180px;
  padding: 6px 13px;
  font: inherit;
  font-size: 12.5px;
  line-height: 1.25;
  white-space: nowrap;
  color: var(--t4);
  background: var(--bg2);
  border: 1px solid var(--b2);
  border-radius: var(--r-pill);
  transition: color .15s ease, background .15s ease, border-color .15s ease;
}
.rs-tn > span { overflow: hidden; text-overflow: ellipsis; }

/* Four states, and they are a sequence rather than a palette: not reached →
   on the stack → next → done. Each is nearer the foreground than the last,
   so depth of colour reads as progress. */
.rs-tn.s-dim     { color: var(--t5); border-color: var(--b1); }
.rs-tn.s-queued  { color: var(--t3); }
.rs-tn.s-done    { color: var(--tx); background: var(--bg4); border-color: transparent; }
.rs-tn.s-skipped { color: var(--t5); border-style: dashed; }

/* The node that pops next. The one thing here that should catch the eye
   before anything else. */
.rs-tn.s-next {
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent);
  font-weight: 600;
}

/* On the live branch and already walked through — inked, not highlighted. */
.rs-tn.on { color: var(--tx); background: var(--bg4); border-color: transparent; }
.rs-tn.on.s-next { color: var(--accent-ink); background: var(--accent); }

.rs-tn.root { font-weight: 600; color: var(--tx); background: var(--bg4); border-color: transparent; }

/* Any node with an id can be clicked to follow that branch, so it has to
   say so under the pointer. */
button.rs-tn { cursor: pointer; }
button.rs-tn:hover { border-color: var(--accent-line); color: var(--accent); }
button.rs-tn.s-done:hover, button.rs-tn.on:hover { background: var(--accent-bg); }
button.rs-tn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }

/* How many leads came out of this node. Without it a node is a name and
   nothing else, and there is no reason to click one. */
.rs-tn-k {
  flex: none;
  min-width: 15px;
  padding: 0 4px;
  font-size: 10px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  text-align: center;
  color: var(--t4);
  background: var(--b1);
  border-radius: var(--r-pill);
}
.rs-tn.on .rs-tn-k, .rs-tn.s-done .rs-tn-k { color: var(--t3); background: var(--b2); }
.rs-tn.s-next .rs-tn-k { color: var(--accent-ink); background: rgba(0, 0, 0, .22); }

/* A new search term handed back by a channel. It re-enters at the root
   rather than going deeper, so it is drawn as leaving. */
.rs-tn.lead {
  border-style: dashed;
  border-color: var(--accent-line);
  color: var(--accent);
  background: transparent;
}

/* "+N more" is a control, not a label. */
.rs-tn.more { border-style: dashed; font-size: 11.5px; padding: 5px 11px; }

/* What the channel actually turned up, with the multiplier on each. */
.rs-tn.find { font-size: 11.5px; padding: 5px 11px; max-width: 200px; }
.rs-tn.find i {
  flex: none;
  font-style: normal;
  font-weight: 600;
  font-size: 10.5px;
  color: var(--accent);
}

/* Walking a branch by hand. The run carries on underneath, so the panel
   says which of the two you are looking at. */
.rs-tree-outer.pinned .rs-tree-edges path.live { stroke-dasharray: 4 3; }
.rs-unpin {
  padding: 3px 10px;
  font: inherit;
  font-size: 11px;
  color: var(--t3);
  background: var(--accent-bg);
  border: 1px solid var(--accent-line);
  border-radius: var(--r-pill);
  cursor: pointer;
}
.rs-unpin strong { color: var(--accent); font-weight: 600; }
.rs-unpin:hover { background: var(--accent-bg-2); }

/* The still on the setup screen, in the same classes so it cannot promise
   one shape and then show another. */
/* Built by the same layout function as the live tree, so it cannot promise
   a shape the real thing does not draw. It only differs in being inert and
   in centring itself rather than scrolling. */
.rs-tree-outer.preview {
  margin-bottom: 20px;
  pointer-events: none;
  user-select: none;
}
.rs-tree-outer.preview .rs-tree { overflow: hidden; }
.rs-tree-outer.preview .rs-canvas { margin: 0 auto; }
.rs-tree-outer.preview .rs-tn { font-size: 11.5px; padding: 5px 11px; max-width: 160px; }
.rs-tree.preview .rs-tn { font-size: 11.5px; padding: 5px 11px; max-width: 160px; }

/* What happens the moment you press Run. It was a line of grey text the
   same size as everything else, saying the one thing on this panel that is
   about to change. */
.rs-next {
  display: flex;
  align-items: center;
  gap: 11px;
  flex-wrap: wrap;
  margin: 18px -16px 0;
  padding: 14px 16px;
  background: var(--accent-bg);
  border-top: 1px solid var(--accent-line);
  box-shadow: inset 3px 0 0 var(--accent);
}
.rs-next-ic {
  flex: none;
  width: 24px; height: 24px;
  display: grid; place-items: center;
  color: var(--accent-ink);
  background: var(--accent);
  border-radius: 50%;
  box-shadow: 0 0 0 4px var(--accent-bg-2);
}
.rs-next-ic svg { width: 14px; height: 14px; }
.rs-next-t { font-size: 14px; font-weight: 600; color: var(--tx); letter-spacing: -.01em; }

/* The tree says what happens next and can never say what just did — that
   node has already been absorbed into the branch. */
.rs-next-last {
  display: flex;
  align-items: baseline;
  gap: 7px;
  margin-left: auto;
  min-width: 0;
  max-width: 46%;
  font-size: 12px;
  color: var(--t4);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rs-next-last strong { overflow: hidden; text-overflow: ellipsis; }
.rs-next-last strong { color: var(--t2); font-weight: 600; }
.rs-next-last-l {
  flex: none;
  font-size: 10px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--t5);
}
.rs-next-last.good strong { color: var(--accent); }
.rs-next-last.warn strong { color: var(--warning); }

/* ── the one-shot lookups ───────────────────────────── */
.rs-ask { display: flex; gap: 8px; margin-bottom: 8px; }
/* Its button is the tool's own, not the brand's: on these screens the
   button IS the feature rather than a step inside one. */
.rs-ask-go { background: var(--tool); }
.rs-ask-go:hover:not(:disabled) { background: var(--tool); filter: brightness(1.08); }
.rs-ask input:focus { border-color: var(--tool); }
.rs-ask input {
  flex: 1;
  min-width: 0;
  padding: 10px 14px;
  font: inherit;
  font-size: 13.5px;
  color: var(--tx);
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-pill);
  outline: none;
  transition: border-color .15s ease;
}
.rs-ask input::placeholder { color: var(--t4); }
.rs-ask input:focus { border-color: var(--accent-line); }

.rs-ask-go {
  flex: none;
  padding: 10px 20px;
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--accent-ink);
  background: var(--accent);
  border: 0;
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: background .15s ease;
}
.rs-ask-go:hover:not(:disabled) { background: var(--accent-hi); }
.rs-ask-go:disabled { opacity: .6; cursor: default; }

/* What it will cost, before it is spent. The whole feature lives inside a
   quota, and a button that does not say what it charges is a trap. */
.rs-ask-cost {
  margin-bottom: 16px;
  font-size: 11.5px;
  line-height: 1.55;
  color: var(--t4);
}

.rs-blank { max-width: 560px; margin: 26px auto 10px; padding: 0 20px 30px; text-align: center; }

/* ── channel competitors ────────────────────────────── */
.rs-target {
  display: flex;
  align-items: center;
  gap: 13px;
  flex-wrap: wrap;
  padding: 14px;
  margin-bottom: 8px;
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-5);
}
.rs-target-av { width: 42px; height: 42px; border-radius: 50%; flex: none; }
.rs-target-b { min-width: 0; }
.rs-target-t { font-size: 14.5px; font-weight: 600; color: var(--tx); }
.rs-target-m { margin-top: 2px; font-size: 12px; color: var(--t3); }

.rs-target-q { display: flex; align-items: center; flex-wrap: wrap; gap: 6px; margin-left: auto; }
.rs-target-ql { font-size: 11px; color: var(--t4); }
.rs-q {
  padding: 3px 9px;
  font-size: 11.5px;
  color: var(--t2);
  background: var(--bg3);
  border-radius: var(--r-pill);
}

.rs-rivals { list-style: none; margin: 0; padding: 0; }

.rs-rival {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 12px;
  border-bottom: 1px solid var(--b0);
}
.rs-rival:last-child { border-bottom: 0; }
.rs-rival:hover { background: var(--bg2); border-radius: var(--r-3); }

/* How many of the searches it turned up in. Once is a coincidence; three out
   of three is the same beat, and that is the whole claim this list makes. */
.rs-rival-rank {
  flex: none;
  width: 38px;
  font-size: 15px;
  font-weight: 600;
  text-align: center;
  color: var(--accent);
  font-variant-numeric: tabular-nums;
}
.rs-rival-rank i { font-size: 11px; font-style: normal; color: var(--t4); }

.rs-rival-av {
  flex: none;
  width: 36px; height: 36px;
  border-radius: 50%;
  background: var(--bg3);
}
.rs-rival-b { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.rs-rival-t { font-size: 13.5px; color: var(--tx); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rs-rival-m { font-size: 11.5px; color: var(--t3); }
.rs-rival-m b { color: var(--t2); font-weight: 600; }
.rs-rival-e {
  font-size: 11px;
  color: var(--t4);
  font-style: italic;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

.rs-rival-add {
  flex: none;
  padding: 6px 14px;
  font: inherit;
  font-size: 12.5px;
  color: var(--t2);
  background: var(--bg3);
  border: 1px solid var(--b1);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.rs-rival-add:hover:not(:disabled) { color: var(--tx); border-color: var(--b3); }
.rs-rival-add:disabled { opacity: .6; cursor: default; }
.rs-rival-on { flex: none; font-size: 11.5px; color: var(--t4); }

/* ── video remakes ──────────────────────────────────── */
.rs-source {
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 12px;
  margin-bottom: 8px;
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-left: 2px solid var(--accent);
  border-radius: var(--r-5);
}
.rs-source-th { flex: none; width: 116px; aspect-ratio: 16/9; border-radius: var(--r-3); overflow: hidden; background: var(--bg3); }
.rs-source-th img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rs-source-b { min-width: 0; }
.rs-source-l {
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--t4);
}
.rs-source-t {
  display: block;
  margin-top: 3px;
  font-size: 14px;
  color: var(--tx);
  text-decoration: none;
}
.rs-source-t:hover { color: var(--accent); }
.rs-source-m { margin-top: 3px; font-size: 12px; color: var(--t3); }

/* How much of the source title this one shares. A bar rather than a number
   alone, because the useful read is "these four are the same video and the
   rest are the same topic", which is a shape. */
.rs-sim {
  position: relative;
  display: flex;
  align-items: center;
  gap: 7px;
  margin-top: 7px;
}
.rs-sim i {
  display: block;
  height: 3px;
  min-width: 2px;
  background: var(--accent);
  border-radius: var(--r-pill);
}
.rs-sim::before {
  content: '';
  position: absolute;
  left: 0; right: 30px;
  height: 3px;
  background: var(--bg4);
  border-radius: var(--r-pill);
}
.rs-sim i { position: relative; z-index: 1; }
.rs-sim b {
  margin-left: auto;
  font-size: 10.5px;
  font-weight: 600;
  color: var(--t4);
  font-variant-numeric: tabular-nums;
}

.rs-note.warn { background: var(--danger-bg); border-left-color: var(--danger); }

/* "Nothing here yet" is .placeholder, the primitive that already exists for
   it. These panels only need it to read as prose rather than as a centred
   label, which is a contextual override and not a new dialect. */
.rs-trail .placeholder,
.rs-finds .placeholder {
  padding: 18px 4px;
  text-align: left;
  line-height: 1.6;
}


/* ── the research database ──────────────────────────── */
.rs-finds-h {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  margin-bottom: 16px;
  padding-bottom: 14px;
  border-bottom: 1px solid var(--b1);
}
.rs-finds-h .rs-col-h { margin-bottom: 0; margin-right: auto; }

.rs-kept {
  padding: 6px 13px;
  font: inherit;
  font-size: 12.5px;
  color: var(--t3);
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-pill);
  cursor: pointer;
  transition: color .15s ease, border-color .15s ease;
}
.rs-kept:hover { color: var(--tx); }
.rs-kept.on { color: var(--accent); border-color: var(--accent-line); background: var(--accent-bg); }

.rs-find-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(214px, 1fr));
  gap: 14px;
}

.rs-find {
  position: relative;
  min-width: 0;
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-4);
  overflow: hidden;
  transition: border-color .15s ease;
}
.rs-find:hover { border-color: var(--b3); }

.rs-find-th {
  position: relative;
  display: block;
  aspect-ratio: 16 / 9;
  background: var(--bg3);
}
.rs-find-th img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* The multiplier is the headline of the whole feature: not how many views,
   but how far past that channel's own normal it went. */
.rs-find-mult {
  position: absolute;
  left: 8px; bottom: 8px;
  padding: 3px 8px;
  font-size: 12px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  color: var(--accent-ink);
  background: var(--accent);
  border-radius: var(--r-pill);
}
.rs-find-short {
  position: absolute;
  right: 8px; bottom: 8px;
  padding: 3px 8px;
  font-size: 11px;
  color: #fff;
  /* A scrim, not a colour: it darkens whatever thumbnail is behind it and is
     correct in both themes precisely because it does not flip. */
  background: rgba(0, 0, 0, .62);
  border-radius: var(--r-pill);
}

.rs-find-b { padding: 10px 11px 12px; }
.rs-find-t {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 13px;
  line-height: 1.4;
  color: var(--tx);
  text-decoration: none;
}
.rs-find-t:hover { color: var(--accent); }
.rs-find-m { margin-top: 5px; font-size: 11.5px; color: var(--t3); }
.rs-find-via { margin-top: 3px; font-size: 11px; color: var(--t4); font-style: italic; }

.rs-star {
  position: absolute;
  top: 8px; right: 8px;
  width: 28px; height: 28px;
  display: grid; place-items: center;
  color: #fff;
  background: rgba(0, 0, 0, .5);
  border: 0; border-radius: 50%;
  cursor: pointer;
  opacity: 0;
  transition: opacity .15s ease, color .15s ease;
}
.rs-star svg { width: 15px; height: 15px; }
.rs-find:hover .rs-star { opacity: 1; }
.rs-star.on { opacity: 1; color: var(--accent); }
@media (hover: none) { .rs-star { opacity: 1; } }

/* ── narrow ─────────────────────────────────────────── */
@media (max-width: 860px) {
  /* Copy first, illustration under it: on a phone the decision matters
     more than the picture of it. */
  .rs-launch { grid-template-columns: minmax(0, 1fr); }
  .rs-launch-art { order: 2; border-right: 0; border-top: 1px solid var(--b1); padding: 18px 16px 0; }
  .rs-launch-b { padding: 20px 18px; }
  .rs-launch-n { font-size: 20px; }
  /* The still is a wide two-column grid at full width; one column here. */
  .rs-still .rs-find-grid { grid-template-columns: minmax(0, 1fr); }
  .rs-stats { margin-left: 0; width: 100%; justify-content: space-between; gap: 12px; }
  .rs-budget { width: 100%; }
  .rs-target-q { margin-left: 0; width: 100%; }
  /* The tree needs width to be a tree. Below this the stack goes above it
     rather than beside it, and the nodes shrink. */
  /* The two setup columns stack, and the illustration goes last — on a
     phone the decisions matter more than the explanation of them. */
  .rs-su-cols { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .rs-su-l { order: 2; }
  .rs-su-t { font-size: 19px; }
  .rs-tree-wrap { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  .rs-tree-outer { padding-left: 0; }
  .rs-lvl-labels { display: none; }
  .rs-tn { padding: 5px 10px; font-size: 11.5px; max-width: 150px; }
  .rs-next-last { margin-left: 0; max-width: 100%; }
  .rs-runs { padding: 8px 12px; }
  .rs-head { padding: 12px; gap: 12px; }
  .rs-source-th { width: 84px; }
}

/* The pulse and the log's slide-in are decoration. The run still works with
   both switched off, which is the test for whether an animation was load
   bearing. */
@media (prefers-reduced-motion: reduce) {
  .rs-go.on { animation: none; }
  .rs-budget-track i, .rs-tn, .rs-find, .rs-launch, .rs-launch-go { transition: none; }
  .rs-launch:hover { transform: none; }
}

/* ── asked before ─────────────────────────────────────
   Both one-shot lookups cache for a fortnight, so re-asking something is
   free. Until these chips existed the cache was a thing that happened to
   you rather than something you could use. */
.rs-recent {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
  margin: -6px 0 18px;
}
.rs-recent-l {
  margin-right: 2px;
  font-size: 10.5px;
  font-weight: 600;
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--t5);
}
.rs-chip-ask {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 220px;
  padding: 4px 10px;
  font: inherit;
  font-size: 12px;
  color: var(--t3);
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-pill);
  cursor: pointer;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transition: color .15s ease, border-color .15s ease;
}
.rs-chip-ask:hover { color: var(--tx); border-color: var(--b3); }

/* ── WHAT EACH TOOL HANDS BACK ────────────────────────
 *
 * The explorer has shown the tree it builds since its setup screen was
 * rebuilt. The other two offered a generic ghost — the same placeholder
 * any empty list in the app gets — which says nothing about what the tool
 * returns, and left two of three features looking unfinished beside the
 * first.
 *
 * Each still is made of that tool's own result components, so it cannot
 * drift from what it promises, and it teaches the thing a sentence cannot:
 * the 3-of-3 and the size verdict for competitors, the drop in the
 * similarity bar for remakes.
 */
.rs-still {
  max-width: 560px;
  margin: 22px auto 0;
  padding: 14px 16px 16px;
  text-align: left;
  background: var(--bg2);
  border: 1px solid var(--b1);
  border-radius: var(--r-4);
  pointer-events: none;
  user-select: none;
  /* An illustration, not a result. It fades out rather than ending, so it
     is not mistaken for data that failed to finish loading. */
  -webkit-mask-image: linear-gradient(to bottom, #000 72%, transparent);
  mask-image: linear-gradient(to bottom, #000 72%, transparent);
}
.rs-still .rs-target { margin-bottom: 4px; padding: 10px 12px; background: var(--bg3); }
.rs-still .rs-target-av { width: 30px; height: 30px; }
.rs-still .rs-target-t { font-size: 13px; }
.rs-still .rs-rival { padding: 8px 10px; }
.rs-still .rs-rival-av { width: 26px; height: 26px; }
.rs-still .rs-rival-t { font-size: 12.5px; }
.rs-still .rs-rival-rank { font-size: 13.5px; }

.rs-still .rs-source { margin-bottom: 12px; padding: 10px; background: var(--bg3); }
.rs-still .rs-source-th { width: 86px; }
.rs-still .rs-source-t { font-size: 13px; }
.rs-still .rs-find-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
.rs-still .rs-find-th { display: block; position: relative; }
.rs-still .rs-find-t { font-size: 12.5px; }

/* "Ask Slate AI what to make" — the step after every tool. The Niche feed's
   button (.co-ai, css/outliers.css), placed where each result ends. */
.rs-finds-h .co-ai { margin-left: 0; }
.rs-ai-row { display: flex; justify-content: flex-end; margin: 4px 0 14px; }
.rs-ai-row .co-ai { margin-left: 0; }

/* "Include Shorts" — the Starred-only chip's twin. Beside Start it sits at
   the end of the row; under the remakes form it trails the cost line. */
.rs-su-go .rs-shorts { margin-left: auto; }
.rs-ask-cost .rs-shorts { margin-left: 8px; vertical-align: middle; }

/* ── HOW FAR ──────────────────────────────────────────
   A setting of the run, so it is drawn like one: a label, a slim ink track
   with a dot at each of the five stops, the chosen stop's name, and one
   quiet line saying what that stop lets in. Ink, not accent — the accent on
   this screen belongs to the run itself.

   The dots are exact. A range thumb's centre travels from half a thumb in
   from the left to half a thumb in from the right, so each dot is drawn as a
   thumb-wide image positioned at its stop's percentage: an image of the
   thumb's width placed at N% has its centre exactly where the thumb's centre
   is at N%. The fill ends at the thumb's centre for the same reason
   (--f is 0 … 1, set inline and while dragging).

   The track is 8px tall and transparent, with the line drawn as a 2px
   stripe through its middle: a track as thin as its line clips the dots to
   2px slivers, which read as dashes. */
.rs-reach { --th: 14px; min-width: 0; }
.rs-reach-top { display: flex; align-items: center; gap: 12px; }
.rs-reach-t { flex: none; font-size: 12px; font-weight: 500; color: var(--t3); }
.rs-reach-v {
  flex: none; min-width: 52px;
  font-size: 12.5px; font-weight: 600; color: var(--tx);
}
.rs-reach-in {
  -webkit-appearance: none; appearance: none;
  flex: 1 1 auto; min-width: 120px; height: 20px; margin: 0;
  background: transparent; cursor: pointer;
  --f: .5;
}
.rs-reach-in::-webkit-slider-runnable-track {
  height: 8px;
  background:
    radial-gradient(circle, var(--c1, var(--t4)) 2.5px, transparent 3px) 0% 50% / var(--th) 8px no-repeat,
    radial-gradient(circle, var(--c2, var(--t4)) 2.5px, transparent 3px) 25% 50% / var(--th) 8px no-repeat,
    radial-gradient(circle, var(--c3, var(--t4)) 2.5px, transparent 3px) 50% 50% / var(--th) 8px no-repeat,
    radial-gradient(circle, var(--c4, var(--t4)) 2.5px, transparent 3px) 75% 50% / var(--th) 8px no-repeat,
    radial-gradient(circle, var(--c5, var(--t4)) 2.5px, transparent 3px) 100% 50% / var(--th) 8px no-repeat,
    linear-gradient(var(--tx), var(--tx)) 0 50% / calc(var(--th) / 2 + (100% - var(--th)) * var(--f)) 2px no-repeat,
    linear-gradient(var(--b2), var(--b2)) 0 50% / 100% 2px no-repeat;
}
.rs-reach-in::-moz-range-track {
  height: 8px;
  background:
    radial-gradient(circle, var(--c1, var(--t4)) 2.5px, transparent 3px) 0% 50% / var(--th) 8px no-repeat,
    radial-gradient(circle, var(--c2, var(--t4)) 2.5px, transparent 3px) 25% 50% / var(--th) 8px no-repeat,
    radial-gradient(circle, var(--c3, var(--t4)) 2.5px, transparent 3px) 50% 50% / var(--th) 8px no-repeat,
    radial-gradient(circle, var(--c4, var(--t4)) 2.5px, transparent 3px) 75% 50% / var(--th) 8px no-repeat,
    radial-gradient(circle, var(--c5, var(--t4)) 2.5px, transparent 3px) 100% 50% / var(--th) 8px no-repeat,
    linear-gradient(var(--b2), var(--b2)) 0 50% / 100% 2px no-repeat;
}
/* Stops already passed are ink, like the fill they sit on. */
.rs-reach-in[data-l="2"] { --c1: var(--tx); }
.rs-reach-in[data-l="3"] { --c1: var(--tx); --c2: var(--tx); }
.rs-reach-in[data-l="4"] { --c1: var(--tx); --c2: var(--tx); --c3: var(--tx); }
.rs-reach-in[data-l="5"] { --c1: var(--tx); --c2: var(--tx); --c3: var(--tx); --c4: var(--tx); }
.rs-reach-in::-moz-range-progress { height: 8px; background: linear-gradient(var(--tx), var(--tx)) 0 50% / 100% 2px no-repeat; }
.rs-reach-in::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none;
  width: var(--th); height: var(--th); margin-top: -3px; border-radius: 50%;
  background: var(--bg); border: 1.5px solid var(--tx);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
  transition: transform .12s cubic-bezier(.2, 0, 0, 1);
}
.rs-reach-in::-moz-range-thumb {
  width: 11px; height: 11px; border-radius: 50%;
  background: var(--bg); border: 1.5px solid var(--tx);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .12);
}
.rs-reach-in:hover::-webkit-slider-thumb { transform: scale(1.08); }
.rs-reach-in:focus-visible { outline: none; }
.rs-reach-in:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--accent-line); }
.rs-reach-in:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 3px var(--accent-line); }
.rs-reach-d {
  margin: 4px 0 0; font-size: 11.5px; line-height: 1.45; color: var(--t4);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* In the run's header: between the controls and the counters, taking the
   room that used to be empty. The caption lines up under the track. */
.rs-head-reach { flex: 1 1 300px; max-width: 440px; min-width: 240px; margin: 0 8px 0 12px; }
.rs-head-reach .rs-reach-d { padding-left: 54px; }

/* On setup it is a step of its own, so the caption may wrap. */
.rs-su-step .rs-reach { max-width: 440px; }
.rs-su-step .rs-reach-d { white-space: normal; padding-left: 54px; }

@media (max-width: 760px) {
  .rs-head-reach { order: 3; flex-basis: 100%; max-width: none; margin: 4px 0 0; }
}
@media (prefers-reduced-motion: reduce) {
  .rs-reach-in::-webkit-slider-thumb { transition: none; }
}
