/* engine / engine.css
   The diagram layer: stage, tiers, groups, nodes, edges, trace, packets,
   inspector panel. Everything draws with the shared token variables
   (--ink --panel --panel-2 --rule --text --dim --faint --signal
   --signal-dim), so a theme restyles the engine for free. Consumers with
   different chrome (page shell, live app) share this file verbatim. */

#viewport{position:absolute;inset:0;overflow:auto;scrollbar-width:thin}
#viewport::-webkit-scrollbar{width:10px;height:10px}
#viewport::-webkit-scrollbar-thumb{background:var(--rule);border-radius:5px}
#sizer{position:relative}
#stage{
  position:absolute;top:0;left:0;transform-origin:0 0;
  width:calc(var(--stage-w)*1px);height:calc(var(--stage-h)*1px);
}
#conn{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}

.tierlab{
  position:absolute;left:0;font-size:9px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--faint);font-weight:600;white-space:nowrap;
}
.tierlab[data-tier]{cursor:pointer;pointer-events:auto}
.tierlab[data-tier]:hover{color:var(--text)}
.tierlab[data-sel="1"]{color:var(--signal)}
.tierlab.note{pointer-events:none}
.tierrule{position:absolute;left:0;height:1px;background:var(--rule);opacity:.5;pointer-events:none}
.grouprect{
  position:absolute;border:1px dashed var(--rule);border-radius:6px;pointer-events:none;
}
.grouprect span{
  position:absolute;top:-8px;left:10px;padding:0 6px;background:var(--ink);
  font-size:9px;letter-spacing:.18em;text-transform:uppercase;color:var(--faint);
  pointer-events:auto;cursor:pointer;
}
.grouprect span:hover{color:var(--text)}
.grouprect[data-sel="1"]{border-color:var(--signal);border-style:solid}
.grouprect[data-sel="1"] span{color:var(--signal)}

/* ── node ───────────────────────────────────────────────── */
.node{
  position:absolute;border:1px solid;border-radius:4px;padding:7px 9px;
  background:var(--panel-2);cursor:pointer;overflow:hidden;
  transition:opacity .22s,filter .22s,transform .12s,box-shadow .22s;
}
.node:hover{transform:translateY(-1px)}
.node .lab{font-weight:600;font-size:13px;line-height:1.2;letter-spacing:-.01em}
.node .sub{font-size:10px;color:var(--dim);margin-top:2px;line-height:1.25}
.node .addr{font-family:var(--mono);font-size:10px;margin-top:3px;letter-spacing:-.02em}
.node .nhead{display:flex;flex-direction:row;align-items:flex-start;gap:8px}
.node .nhead .ntext{min-width:0;flex:1}
.node .glyph{
  flex:none;font-size:26px;line-height:1;opacity:.9;
  display:flex;align-items:center;justify-content:center;width:30px;
}
.node[data-size="hero"] .glyph{font-size:32px;width:36px}
.node[data-size="compact"] .glyph{font-size:15px;width:18px}
.node .pill{
  flex:none;align-self:flex-start;
  font-family:var(--mono);font-size:9px;line-height:1;letter-spacing:.04em;
  padding:3px 5px;border-radius:3px;
  background:color-mix(in srgb,var(--text) 8%,transparent);
  border:1px solid var(--rule);color:var(--dim);
}
.node .pill[data-empty="1"]{min-width:26px;height:15px;opacity:.5}
.node .pill[data-tone="ok"]{
  color:var(--ok,var(--dim));border-color:var(--ok,var(--rule));
  background:color-mix(in srgb,var(--ok,var(--text)) 10%,transparent);
}
.node .pill[data-tone="err"]{
  color:var(--err,var(--dim));border-color:var(--err,var(--rule));
  background:color-mix(in srgb,var(--err,var(--text)) 10%,transparent);
}
.node .pill[data-tone="warn"]{
  color:var(--warn,var(--dim));border-color:var(--warn,var(--rule));
  background:color-mix(in srgb,var(--warn,var(--text)) 10%,transparent);
}
.node .ncols{display:flex;align-items:center;gap:10px}
.node .nleft{min-width:0;flex:1}
.node .nright{flex:none;display:flex;align-items:center}
.node .metrics{display:flex;flex-direction:column;align-items:flex-end;gap:2px}
.node .metrics span{display:flex;align-items:baseline;gap:6px}
.node .metrics i{font-style:normal;font-size:9px;color:var(--faint)}
.node .metrics b{font-family:var(--mono);font-size:10px;font-weight:600}
.node .chev{
  position:absolute;bottom:5px;right:7px;
  font-family:var(--mono);font-size:9px;letter-spacing:.02em;
  color:var(--faint);border:1px solid transparent;border-radius:3px;
  padding:2px 5px;line-height:1;
}
.node:hover .chev{
  color:var(--accent);border-color:var(--accent);
  background:color-mix(in srgb,var(--accent) 10%,transparent);
}
.node .badges{display:flex;gap:3px;margin-top:4px;flex-wrap:wrap}
.node .badges b{
  font-weight:600;font-size:8px;letter-spacing:.07em;text-transform:uppercase;
  padding:1px 4px;border-radius:2px;background:#ffffff14;color:var(--dim);
}
.node[data-state="stopped"],.node[data-state="offline"]{
  border-style:dashed;filter:saturate(.25);opacity:.72;
}
.node[data-state="planned"]{background:transparent;border-style:dotted;opacity:.6}

#tourpick select.ctl{
  font:inherit;color:var(--text);background:var(--panel-2);
  border:1px solid var(--rule);border-radius:3px;padding:4px 8px;cursor:pointer;
}
/* ── search ─────────────────────────────────────────────── */
#search{position:relative}
#searchbox{
  font:inherit;color:var(--text);background:var(--panel-2);
  border:1px solid var(--rule);border-radius:3px;padding:4px 9px;width:150px;
  transition:width .15s,border-color .15s;
}
#searchbox:focus{width:220px;border-color:var(--signal);outline:none}
#searchbox::placeholder{color:var(--faint)}
#searchlist{
  display:none;position:absolute;top:calc(100% + 5px);right:0;z-index:30;
  min-width:240px;max-width:330px;max-height:320px;overflow-y:auto;
  background:var(--panel);border:1px solid var(--rule);border-radius:4px;
  box-shadow:0 10px 30px -12px #0008;
}
#searchlist.on{display:block}
#searchlist .row{
  display:block;width:100%;text-align:left;padding:6px 10px;
  border-bottom:1px solid var(--rule);cursor:pointer;
}
#searchlist .row:last-child{border-bottom:none}
#searchlist .row:hover,#searchlist .row[data-hot="1"]{background:var(--panel-2)}
#searchlist .row b{font-weight:600;font-size:12px}
#searchlist .row small{
  display:block;font-size:10px;color:var(--dim);font-family:var(--mono);
}
#searchlist .empty{padding:8px 10px;color:var(--dim);font-size:12px}

/* while searching: matches glow, everything else recedes */
#stage[data-search="on"] .node{opacity:.22;filter:saturate(.25)}
#stage[data-search="on"] .node.smatch{
  opacity:1;filter:none;border-color:var(--signal)!important;
  box-shadow:0 0 0 1px var(--signal),0 0 20px -5px var(--signal);
}
#stage[data-search="on"] .edge{opacity:.1}
#stage[data-search="on"] .edgelab{opacity:.12}

/* size variants — a view concern, set via view.yaml sizes: */
.node[data-size="hero"] .lab{font-size:16px}
.node[data-size="hero"] .sub{font-size:11px}
.node[data-size="hero"] .addr{font-size:11px}
.node[data-size="hero"]{border-width:2px;padding:10px 13px}
.node[data-size="tall"]{padding:10px 11px}
.node[data-size="tall"] .badges{flex-direction:column;align-items:flex-start}
.node[data-size="compact"]{padding:5px 8px}
.node[data-size="compact"] .lab{font-size:11px;font-weight:500}
.node[data-size="compact"] .sub,.node[data-size="compact"] .addr,
.node[data-size="compact"] .badges,.node[data-size="compact"] .metrics{display:none}

.node[data-size="bulkhead-v"]{
  display:flex;align-items:center;justify-content:center;
  padding:12px 2px;border-style:double;border-width:3px;overflow:visible;
}
.node[data-size="bulkhead-v"] .lab{
  writing-mode:vertical-rl;font-size:10px;font-weight:600;
  letter-spacing:.22em;text-transform:uppercase;
}
.node[data-size="bulkhead-v"] .sub,.node[data-size="bulkhead-v"] .addr,
.node[data-size="bulkhead-v"] .badges{display:none}
.node[data-size="bulkhead-v"] .nhead{flex-direction:column;align-items:center;gap:6px}
.node[data-size="bulkhead"],.node[data-size="bulkhead-h"]{
  display:flex;align-items:center;justify-content:center;gap:10px;
  padding:2px 12px;border-style:double;border-width:3px;overflow:visible;
}
.node[data-size="bulkhead"] .lab,.node[data-size="bulkhead-h"] .lab{
  font-size:10px;font-weight:600;letter-spacing:.22em;text-transform:uppercase;
}
.node[data-size="bulkhead"] .sub,.node[data-size="bulkhead-h"] .sub{margin-top:0;font-size:9px}
.node[data-size="bulkhead"] .addr,.node[data-size="bulkhead"] .badges,
.node[data-size="bulkhead-h"] .addr,.node[data-size="bulkhead-h"] .badges{display:none}

.node[data-size="bulkhead"] .chev,.node[data-size="bulkhead-h"] .chev{bottom:auto;top:50%;transform:translateY(-50%)}

/* selection — visible in normal mode too, not only under trace */
.node.sel{
  border-color:var(--signal)!important;
  box-shadow:0 0 0 1.5px var(--signal),0 0 16px -6px var(--signal);
}

/* trace mode — the signature */
#stage[data-trace="on"] .node{opacity:.14;filter:saturate(.1)}
#stage[data-trace="on"] .node.lit{opacity:1;filter:none}
#stage[data-trace="on"] .node.sel{
  opacity:1;filter:none;border-color:var(--signal)!important;
  box-shadow:0 0 0 1px var(--signal),0 0 26px -4px var(--signal);
}
#stage[data-trace="on"] .edge{opacity:.07}
#stage[data-trace="on"] .edge.lit{opacity:1;stroke:var(--signal);stroke-width:2}
#stage[data-trace="on"] .edgelab{opacity:.1}
#stage[data-trace="on"] .edgelab.lit{opacity:1}
.pkt{pointer-events:none}
.pkt-implicit circle{opacity:.6}
.pktlab{
  font-family:var(--mono);font-size:8.5px;letter-spacing:-.02em;
  paint-order:stroke;stroke:var(--ink);stroke-width:3.5px;stroke-linejoin:round;
}
.edge.surge{stroke:var(--signal)!important;stroke-width:2.6!important;opacity:1!important}
.node.hit{
  border-color:var(--signal)!important;
  box-shadow:0 0 0 1px var(--signal),0 0 30px -6px var(--signal);
}
#stage[data-trace="on"] .edge.surge{opacity:1!important}
#stage[data-trace="on"] .node.hit{opacity:1;filter:none}

.edge{fill:none;stroke-linecap:round;transition:opacity .22s,stroke .22s}
.edgelab{
  font-family:var(--mono);font-size:9px;fill:var(--dim);
  paint-order:stroke;stroke:var(--ink);stroke-width:4px;stroke-linejoin:round;
  transition:opacity .22s;
}

/* ── panel ──────────────────────────────────────────────── */
#panel{
  flex:none;width:0;overflow:hidden;background:var(--panel);
  border-left:1px solid transparent;position:relative;
  transition:width .26s cubic-bezier(.4,0,.2,1),border-color .26s;
  display:flex;flex-direction:column;
}
#panel.open{width:min(400px,42vw);border-left-color:var(--rule)}
#panel>*{min-width:min(400px,42vw)}
@media (max-width:820px){
  #panel{position:absolute;top:0;right:0;bottom:0;z-index:6}
  #panel.open{width:88vw}
  #panel>*{min-width:88vw}
}
/* header cluster: eyebrow chip (tag colour dot · kind · tag name),
   title, meta — the rules target the ids the consumer markup carries;
   an empty line drops out so the cluster never stacks on nothing */
#peyebrow{display:flex;align-items:center;gap:7px;padding:16px 18px 0;
  font-size:calc(var(--chrome,14px) - 5px);letter-spacing:.2em;
  text-transform:uppercase;color:var(--dim)}
#peyebrow::before{content:'';flex:none;width:7px;height:7px;border-radius:50%;
  background:var(--eb-dot,var(--faint))}
#peyebrow:empty{display:none}
#ptitle{padding:6px 18px 0;margin:0;font-size:calc(var(--chrome,14px) + 5px);
  font-weight:700;letter-spacing:-.02em}
#pmeta{padding:6px 18px 14px;font-family:var(--mono);
  font-size:calc(var(--chrome,14px) - 3px);color:var(--dim);
  border-bottom:1px solid var(--rule)}
#pmeta:empty{display:none}
#panel:has(#peyebrow:empty) #ptitle{padding-top:16px}
#panel:has(#pmeta:empty) #ptitle{padding-bottom:14px;border-bottom:1px solid var(--rule)}
#panel .close{position:absolute;top:14px;right:14px;color:var(--dim);font-size:16px;line-height:1}
#panel .close:hover{color:var(--text)}
#pbody{padding:16px 18px;overflow-y:auto;flex:1}
#pbody p{margin-bottom:10px;color:#cfd6e2}
#pbody ul{margin:0 0 10px 16px}
#pbody li{margin-bottom:4px}
#pbody code{font-family:var(--mono);font-size:calc(var(--chrome,14px) - 2px);background:#ffffff10;padding:1px 4px;border-radius:2px}
.note{border-left:2px solid var(--faint);padding:2px 0 2px 10px;margin:0 0 10px}
.note b{display:block;font-size:calc(var(--chrome,14px) - 5px);letter-spacing:.16em;text-transform:uppercase;margin-bottom:2px}
.plinks{margin-top:14px;padding-top:12px;border-top:1px solid var(--rule)}
.plinks a{display:block;color:var(--signal);font-size:calc(var(--chrome,14px) - 2px);text-decoration:none;margin-bottom:5px}
.plinks a:hover{text-decoration:underline}

/* ── engine additions ───────────────────────────────────── */
/* inspector data rows — provider-supplied key/value pairs */
.prows{margin:0 0 12px;border:1px solid var(--rule);border-radius:4px;overflow:hidden}
.prow{display:flex;justify-content:space-between;gap:10px;padding:5px 9px;border-bottom:1px solid var(--rule)}
.prow:last-child{border-bottom:none}
.prow span{color:var(--dim);font-size:calc(var(--chrome,14px) - 3px)}
.prow b{font-family:var(--mono);font-size:calc(var(--chrome,14px) - 3px);font-weight:600;text-align:right}
.pprov{margin-top:12px;padding-top:10px;border-top:1px solid var(--rule);
  color:var(--faint);font-size:calc(var(--chrome,14px) - 4px);font-style:italic}

/* dashed self-loop — work happening off the request path */
.selfloop{fill:none;stroke:var(--dim);stroke-width:1.4;stroke-dasharray:4 4;opacity:.9}
.selflooplab{font-family:var(--mono);font-size:9px;fill:var(--dim);
  paint-order:stroke;stroke:var(--ink);stroke-width:3.5px;stroke-linejoin:round}
.selfloopg.remnant .selfloop{opacity:.3}

/* ── group legend disclosure ─────────────────────────────
   The engine owns this markup, so it owns its behaviour styling. The panel
   chrome around #groups (position, background, border) stays the consumer's. */
#groups .ghead{
  display:flex;align-items:center;gap:6px;width:100%;
  background:none;border:none;padding:0 0 4px;margin:0;
  font:inherit;color:inherit;cursor:pointer;text-align:left;
}
#groups .ghead h4{margin:0}
#groups .gchev{
  font-size:9px;color:var(--faint);flex:none;line-height:1;
  transition:transform .15s ease;
}
#groups .gsum{
  margin-left:auto;font-family:var(--mono);color:var(--faint);
  font-size:calc(var(--chrome,14px) - 6px);
}
#groups .gbody{display:flex;flex-direction:column;gap:1px}
#groups[data-open="0"] .gbody{display:none}
#groups[data-open="0"] .gchev{transform:rotate(-90deg)}
#groups[data-open="0"] .ghead{padding-bottom:0}
#groups .ghead:hover .gchev,#groups .ghead:hover h4{color:var(--text)}
