/* Strict 3-panel workspace: a left rail (Query/Library/Filters/
   Constraints/Pipeline/Review, collapsible via its own hamburger toggle)
   with ONE active step's content in the center at a time — the Query step
   holds the full query editor (single molecule + batch), selected by
   default — and a compact sticky right-side run summary, plus a bottom
   run drawer that only exists while a run is active.
*/
.wf-rows{ display:flex; flex-direction:column; gap:16px; max-width:2200px; margin:0 auto; width:100%; }
.wf-topbar-row{ display:flex; align-items:center; gap:14px; }
.wf-topbar-thumb{ width:52px; height:52px; flex:none; border:1px solid var(--line); border-radius:8px; background:var(--panel); display:flex; align-items:center; justify-content:center; overflow:hidden; }
.wf-topbar-thumb svg{ width:100%; height:100%; }
.wf-topbar-meta{ flex:1; min-width:0; }
.wf-topbar-name{ font-weight:700; font-size:13.5px; }
.wf-topbar-smiles{ font-size:11.5px; color:var(--muted); white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.wf-topbar-nav{ display:flex; align-items:center; gap:8px; flex:none; }
.wf-topbar-nav .field-note{ min-width:110px; text-align:center; }
.smiles-copy-btn{
  position:absolute; right:6px; top:50%; transform:translateY(-50%); width:24px; height:24px;
  border:none; background:transparent; color:var(--muted); cursor:pointer; border-radius:5px;
  display:flex; align-items:center; justify-content:center; padding:0;
}
.smiles-copy-btn:hover{ background:var(--panel); color:var(--accent); }
.smiles-copy-btn.copied{ color:var(--good-text); }

.wf-shell{ display:grid; grid-template-columns:196px minmax(0,1fr) 300px; gap:16px; align-items:start; transition:grid-template-columns .15s ease; }
.wf-shell.rail-collapsed{ grid-template-columns:48px minmax(0,1fr) 300px; }
.wf-shell.rail-collapsed .wf-rail-heading,
.wf-shell.rail-collapsed .wf-rail-item{ display:none; }
.wf-rail{
  display:flex; flex-direction:column; gap:2px; position:sticky; top:0;
  background:var(--accent-dark); border:1px solid var(--accent-dark); border-radius:12px; padding:14px 10px;
  overflow:hidden; min-width:0;
}
.wf-rail-toggle{
  display:flex; align-items:center; justify-content:center; width:28px; height:28px; flex:none;
  border:1px solid rgba(255,255,255,0.25); border-radius:8px; background:transparent; color:rgba(255,255,255,0.75); cursor:pointer;
  margin-bottom:8px; padding:0;
}
.wf-rail-toggle:hover{ color:#fff; border-color:#fff; }
.wf-rail-heading{
  font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:rgba(255,255,255,0.55);
  padding:2px 10px 10px; margin-bottom:4px; border-bottom:1px solid rgba(255,255,255,0.12);
}
.wf-rail-item{
  display:flex; align-items:center; gap:10px; padding:10px; border-radius:8px; border:1px solid transparent;
  background:none; font:inherit; font-size:13px; text-align:left; cursor:pointer; color:rgba(255,255,255,0.85); width:100%;
  position:relative;
}
/* Connecting timeline line between step dots, like the reference mockup's
   stepper — skipped on the last item (nothing below it to connect to). */
.wf-rail-item:not(:last-child)::after{
  content:""; position:absolute; left:19px; top:36px; width:1.5px; height:16px; background:rgba(255,255,255,0.18);
}
.wf-rail-item:hover{ background:rgba(255,255,255,0.06); }
.wf-rail-item.active{ background:var(--accent); color:#fff; font-weight:700; }
.wf-rail-item[disabled]{ color:rgba(255,255,255,0.35); cursor:not-allowed; opacity:0.6; }
.wf-rail-dot{
  width:22px; height:22px; flex:none; border-radius:50%; display:flex; align-items:center; justify-content:center;
  font-size:11px; font-weight:700; border:1.5px solid rgba(255,255,255,0.35); color:rgba(255,255,255,0.85); background:transparent;
  position:relative; z-index:1;
}
.wf-rail-item.complete .wf-rail-dot{ background:var(--accent); border-color:var(--accent); color:#fff; }
.wf-rail-item.active .wf-rail-dot{ background:#fff; border-color:#fff; color:var(--accent); }

/* Stretched to match the tallest column in the row (rail / run summary)
   so a short step's content (e.g. Review) fills the space down to the run
   drawer instead of leaving a block of empty page below the card — the
   rail and run-rail stay top-aligned (align-items:start on .wf-shell) so
   their own nav/summary boxes don't grow oddly tall on short steps. */
.wf-steps-host{ min-width:0; display:flex; flex-direction:column; gap:16px; align-self:stretch; }
.wf-step{ display:none; flex-direction:column; gap:16px; }
.wf-step.active{ display:flex; flex:1; }
.wf-step.active > .section:last-child{ flex:1 1 auto; }

.wf-run-rail{ display:flex; flex-direction:column; gap:16px; min-width:0; position:sticky; top:0; }
.run-action-card{ padding:14px 15px; }

/* .wf-run-drawer (the docked Active Status bar) now lives in shell.css —
   it's a global shell element visible on every tab, not workflow-specific
   markup, since it moved out of .wf-rows. */

@media (max-width:1100px){
  .wf-shell{ grid-template-columns:1fr; }
  .wf-rail{ flex-direction:row; overflow-x:auto; position:static; gap:6px; }
  .wf-rail-item{ width:auto; white-space:nowrap; }
}
@media (max-width:700px){
  .wf-topbar-row{ flex-wrap:wrap; }
  .wf-topbar-nav{ width:100%; justify-content:space-between; }
}
#catalogChecklist{ max-height:260px; overflow-y:auto; }
.filters-toggle{ display:flex; align-items:center; justify-content:space-between; cursor:pointer; }
.filters-toggle .chev{ transition:transform .15s; color:var(--muted); }
.filters-toggle.open .chev{ transform:rotate(90deg); }
.filters-body{ display:none; margin-top:10px; }
.filters-body.open{ display:block; }

/* ---- structural/pharmacophore constraint editor ---- */
/* Two-column layout matching the reference mockup: feature list + selected
   constraints on the left, the interactive structure + legend on the
   right — rather than everything stacked in one column. */
.constraint-2col{ display:grid; grid-template-columns:minmax(240px,320px) minmax(0,1fr); gap:20px; align-items:start; }
@media (max-width:900px){ .constraint-2col{ grid-template-columns:1fr; } }
/* Large, central, real interactive structure — real per-atom pixel
   coordinates from the server (rdMolDraw2D's GetDrawCoords, which works
   for every atom, not just labeled heteroatoms) let us overlay genuine
   clickable hit-regions directly inside the same <svg> the structure is
   drawn in, so no separate scaling/transform math is needed. */
.constraint-structure-host{
  width:100%; min-height:300px; border:1px solid var(--line); border-radius:10px; background:var(--panel);
  display:flex; align-items:center; justify-content:center; overflow:hidden; position:relative;
}
.constraint-structure-host svg{ width:100%; height:auto; max-height:380px; }
.constraint-atom-hit{ fill:transparent; cursor:pointer; }
.constraint-atom-hit:hover{ fill:rgba(30,122,111,0.18); }
.constraint-highlight-required{ fill:rgba(30,122,111,0.30); stroke:var(--accent); stroke-width:1.5; pointer-events:none; }
.constraint-highlight-excluded{ fill:rgba(161,38,34,0.22); stroke:var(--crit-text); stroke-width:1.5; pointer-events:none; }
.constraint-highlight-preview{ fill:none; stroke:var(--accent-dark); stroke-width:2; stroke-dasharray:3 2; pointer-events:none; }
/* Selection ring — a distinct focus indicator, independent of the
   Required/Excluded persisted-state colors above, so "selected" and
   "constrained" are always visually distinguishable even on the same atom. */
.constraint-highlight-selected{ fill:none; stroke:#c9971e; stroke-width:2.5; stroke-dasharray:4 2; pointer-events:none; }
.constraint-empty-hint{ color:var(--muted); font-size:12.5px; padding:20px; text-align:center; }
/* Freeform lasso/box-select path, drawn live while dragging on empty
   structure space. */
.constraint-lasso{ fill:rgba(30,122,111,0.12); stroke:var(--accent); stroke-width:1.5; stroke-dasharray:4 3; pointer-events:none; }

.constraint-instance-list{ max-height:280px; overflow-y:auto; display:flex; flex-direction:column; gap:6px; }
.constraint-row{ display:flex; align-items:center; gap:10px; padding:8px; border:1px solid var(--line); border-radius:8px; cursor:pointer; }
.constraint-row:hover{ border-color:var(--accent); }
.constraint-row.state-required{ border-color:var(--accent); background:var(--seq-100); }
.constraint-row.state-excluded{ border-color:var(--crit-border); background:var(--crit-bg); }
.constraint-row.selected{ outline:2px solid #c9971e; outline-offset:1px; }
.constraint-selection-bar{
  display:flex; align-items:center; gap:6px; margin-top:8px; padding:8px 10px;
  border:1px solid #c9971e; background:rgba(201,151,30,0.1); border-radius:8px;
}
.constraint-thumb{ width:56px; height:44px; flex:none; border-radius:4px; overflow:hidden; background:var(--bg); display:flex; align-items:center; justify-content:center; }
.constraint-thumb svg{ width:100%; height:100%; }
.constraint-label{ flex:1; min-width:0; font-size:13px; font-weight:600; white-space:normal; line-height:1.3; }
.constraint-state-select{
  flex:none; width:auto; font-family:inherit; font-size:11.5px; font-weight:700; padding:0 8px; height:28px; min-height:28px;
  border-radius:7px; border:1px solid var(--line); background:var(--bg); color:var(--muted); cursor:pointer;
}
.constraint-state-select.state-required{ background:var(--seq-100); border-color:var(--accent); color:var(--accent-dark); }
.constraint-state-select.state-excluded{ background:var(--crit-bg); border-color:var(--crit-border); color:var(--crit-text); }
.constraint-selected-tag{ display:inline-flex; align-items:center; gap:4px; padding:3px 8px; border-radius:7px; font-size:11.5px; font-weight:600; margin:2px 4px 2px 0; }
.constraint-selected-tag.required{ background:var(--seq-100); color:var(--accent-dark); border:1px solid var(--accent); }
.constraint-selected-tag.excluded{ background:var(--crit-bg); color:var(--crit-text); border:1px solid var(--crit-border); }
.constraint-selected-tag [data-remove]{ cursor:pointer; font-weight:700; }

/* ---- workflow builder ---- */
.stage-flow{ display:flex; align-items:center; gap:0; flex-wrap:wrap; row-gap:10px; margin:4px 0 12px; }
.stage-card{
  display:flex; flex-direction:column; gap:8px; background:var(--panel); border:1px solid var(--line);
  border-radius:10px; padding:10px 12px; width:216px; flex:none; cursor:grab;
}
.stage-card.dragging{ opacity:0.35; }
.stage-card.drag-over{ border-color:var(--accent); box-shadow:0 0 0 2px rgba(30,122,111,0.25); }
.stage-card-head{ display:flex; align-items:center; gap:6px; }
.stage-grip{ width:14px; height:14px; flex:none; border-radius:2px;
  background-image:radial-gradient(circle, var(--muted) 1.1px, transparent 1.1px);
  background-size:4px 4px; opacity:0.65; }
.stage-method-label{ font-weight:700; font-size:12.5px; flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.stage-remove{ border:none; background:transparent; color:var(--muted); cursor:pointer; font-size:16px; line-height:1; padding:0 2px; flex:none; }
.stage-remove:hover{ color:var(--crit-text); }
.stage-pct-row{ display:flex; align-items:center; gap:5px; font-size:11.5px; color:var(--muted); flex-wrap:wrap; }
.stage-pct-row select.stage-retention-mode{ flex:1 1 100%; padding:4px 5px; font-size:11px; }
.stage-pct-row input{ width:60px; padding:4px 6px; font-size:12px; }
.stage-chevron{ flex:none; width:22px; display:flex; align-items:center; justify-content:center; color:var(--muted); align-self:center; }
.stage-add-wrap{ position:relative; flex:none; }
.stage-add-btn{
  display:flex; flex-direction:column; align-items:center; justify-content:center; gap:3px;
  width:94px; height:76px; border:1.5px dashed var(--line); border-radius:10px; background:transparent;
  color:var(--muted); cursor:pointer; font-size:11.5px; font-weight:600; font-family:inherit;
}
.stage-add-btn:hover{ border-color:var(--accent); color:var(--accent); }
.stage-add-plus{ font-size:18px; line-height:1; }
.stage-add-menu{
  position:absolute; top:calc(100% + 6px); left:0; z-index:10; background:var(--bg); border:1px solid var(--line);
  border-radius:8px; box-shadow:0 8px 24px var(--shadow); padding:5px; display:none; min-width:160px;
}
.stage-add-menu.open{ display:block; }
.stage-add-menu button{ display:block; width:100%; text-align:left; padding:7px 10px; border:none; background:transparent;
  cursor:pointer; font-size:12.5px; border-radius:6px; font-family:inherit; color:var(--border); }
.stage-add-menu button:hover{ background:var(--panel); }
/* categorized method picker (2D Circular / Structural-Topological / Pharmacophore / 3D) */
.method-menu{ width:300px; max-height:360px; overflow-y:auto; }
.method-menu-family{ font-size:10.5px; font-weight:700; text-transform:uppercase; letter-spacing:.04em; color:var(--accent); padding:6px 8px 2px; }
.method-menu-item{ display:block; width:100%; text-align:left; padding:6px 8px; border:none; background:transparent; cursor:pointer; border-radius:6px; font-family:inherit; }
.method-menu-item:hover{ background:var(--panel); }
.method-menu-item[disabled]{ cursor:not-allowed; opacity:0.45; }
.method-menu-item[disabled]:hover{ background:transparent; }
.method-menu-item-label{ font-size:12.5px; font-weight:700; }
.method-menu-item-meta{ font-size:10.5px; color:var(--muted); margin-top:1px; }
.method-menu-item-desc{ font-size:11px; color:var(--muted); margin-top:2px; line-height:1.35; }
.method-card{
  display:flex; flex-direction:column; gap:6px; background:var(--panel); border:1px solid var(--line);
  border-radius:10px; padding:10px 12px; width:200px; flex:none;
}
.method-card-head{ display:flex; align-items:center; gap:6px; }
.method-card-label{ font-weight:700; font-size:12.5px; flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }
.method-card select{ width:100%; font-size:11.5px; padding:4px 6px; }
.method-card input[type=number]{ width:60px; font-size:12px; padding:4px 6px; }
.method-card-row{ display:flex; align-items:center; gap:6px; font-size:11px; color:var(--muted); }
.preset-row{ display:flex; gap:8px; flex-wrap:wrap; align-items:center; }
.preset-row .field-note{ margin-right:2px; }

/* ---- funnel ---- */
.funnel{ display:flex; flex-direction:column; gap:7px; }
.funnel-row{ display:grid; grid-template-columns:118px 1fr 64px; align-items:center; gap:8px; cursor:pointer; border-radius:6px; padding:2px 4px; margin:-2px -4px; }
.funnel-row:hover{ background:var(--panel); }
.funnel-label{ font-size:11.5px; color:var(--muted); text-align:right; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; }
.funnel-track{ height:18px; background:var(--panel); border-radius:4px; overflow:hidden; border:1px solid var(--line); }
.funnel-fill{ height:100%; border-radius:3px 0 0 3px; }
.funnel-count{ font-size:11.5px; font-weight:700; font-variant-numeric:tabular-nums; }
.funnel-meta{ font-size:10.5px; color:var(--muted); grid-column:2; margin-top:-3px; }

/* ---- animated funnel: strategy-aware, aggregated (not per-compound) ---- */
.anim-funnel{ display:flex; align-items:center; gap:0; overflow-x:auto; padding:14px 4px 18px; }
.anim-funnel-col{ display:flex; flex-direction:column; align-items:center; gap:10px; flex:none; }
.anim-funnel-block{
  position:relative; border-radius:8px; border:1px solid var(--seq-500); background:var(--seq-300);
  display:flex; flex-direction:column; align-items:center; justify-content:center; padding:10px 12px; min-width:78px;
  transform:scaleX(0.04); transform-origin:left center; transition:transform 0.65s cubic-bezier(.2,.8,.2,1);
  cursor:default;
}
.anim-funnel-block.animate-in{ transform:scaleX(1); }
.anim-funnel-block.final{ background:var(--seq-700); border-color:var(--seq-700); }
.anim-funnel-block.final .afb-label, .anim-funnel-block.final .afb-count{ color:#fff; }
.anim-funnel-block.estimate{ border-style:dashed; opacity:0.75; }
.afb-label{ font-size:10px; font-weight:700; color:var(--accent-dark); white-space:normal; text-align:center; line-height:1.15; max-width:110px; }
.afb-count{ font-size:15px; font-weight:800; font-variant-numeric:tabular-nums; }
.afb-est-tag{ font-size:8.5px; font-weight:700; text-transform:uppercase; letter-spacing:.03em; color:var(--muted); margin-top:1px; }
.anim-funnel-connector{
  position:relative; width:52px; height:4px; flex:none; border-radius:2px;
  background:linear-gradient(90deg, var(--seq-300), var(--seq-500), var(--seq-300));
  background-size:200% 100%; animation:funnelFlow 1.8s linear infinite;
}
@keyframes funnelFlow{ from{ background-position:0% 0; } to{ background-position:-200% 0; } }
/* ---- flowing particles: small dots (volume) + occasional real structure
   thumbnails (realOrSchematicSvg output) riding the same connector, giving
   the funnel a literal "compounds flowing through each stage" motion
   instead of only the static bar-width comparison. Each particle's actual
   @keyframes rule (a distinct one per connector "slot" + particle index) is
   generated at render time in JS (funnelSeqKeyframeRule) and set via
   particle.style.animation directly, NOT this class — see
   renderAnimatedFunnel — so that particles in different pipeline stages
   only move during their own slice of one shared, looping total-cycle
   duration, instead of every stage's particles animating simultaneously
   forever (which didn't represent the real sequential pipeline). Still
   pure CSS @keyframes underneath, no JS requestAnimationFrame loop — the
   <style id="funnelSeqKeyframes"> text is just rebuilt per render. ---- */
.anim-funnel-particle{
  position:absolute; top:50%; left:-6px; width:6px; height:6px; margin-top:-3px;
  border-radius:50%; background:var(--accent); opacity:0;
}
.anim-funnel-particle.has-structure{
  width:22px; height:16.5px; margin-top:-8px; border-radius:3px; background:var(--bg);
  box-shadow:0 1px 4px var(--shadow); display:flex; align-items:center; justify-content:center;
  overflow:hidden; z-index:1;
}
.anim-funnel-particle.has-structure svg{ width:100%; height:100%; }
.anim-funnel-branches{ display:flex; flex-direction:column; gap:8px; }
.anim-funnel-branch-row{ display:flex; align-items:center; gap:0; }
