/* Linked-list drawing (list.js): nodes = value + next slot, SVG arrows, ∅, gliding pointer labels (.ptr from viz.css). */
.ll{
  --ll-v:32px;--ll-s:16px;--ll-h:40px;--ll-gap:26px;--ll-line:60px;
  position:relative;padding:46px 0 24px 20px
}
.ll-svg{position:absolute;inset:0;width:100%;height:100%;overflow:visible;pointer-events:none}
.ll-row{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ll-line) var(--ll-gap);min-height:var(--ll-h)}
.ll-row + .ll-row{margin-top:var(--ll-line)}

.ll-node{
  position:relative;display:flex;height:var(--ll-h);border:1.5px solid var(--ink-4);border-radius:6px;background:var(--paper);
  font-family:var(--mono);font-variant-ligatures:none;
  transition:background-color .25s, border-color .25s, color .25s, opacity .3s
}
.ll-node .v{width:var(--ll-v);display:grid;place-items:center;font-weight:700;font-size:var(--fs-small)}
.ll-node .nx{width:var(--ll-s);border-left:1.5px solid var(--ink-4);display:grid;place-items:center;transition:border-color .25s}
.ll-node .nx::after{content:"";width:5px;height:5px;border-radius:50%;background:var(--ink-2)}
/* next = None: a slash through the empty slot */
.ll-node.null .nx{background:linear-gradient(to top right, transparent calc(50% - 1px), var(--ink-3) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px))}
.ll-node.null .nx::after{display:none}
.ll-node.dummy{border-style:dashed}
.ll-nil{position:relative;height:var(--ll-h);min-width:22px;display:grid;place-items:center;font-family:var(--mono);font-size:var(--fs-body);color:var(--ink-3)}

.ll-node.probe{background:var(--probe-tint);border-color:var(--probe)}
.ll-node.probe .nx{border-color:var(--probe)}
.ll-node.hit{background:var(--mark);border-color:var(--mark);color:var(--on-mark)}
.ll-node.hit .nx{border-color:var(--on-mark)}
.ll-node.hit .nx::after{background:var(--on-mark)}
.ll-node.ok{background:var(--ok-tint);border-color:var(--ok);color:var(--ok)}
.ll-node.ok .nx{border-color:var(--ok)}
.ll-node.ok .nx::after{background:var(--ok)}
.ll-node.used{background:var(--grid);border-color:var(--grid);color:var(--ink-2)}
.ll-node.skip{opacity:.35;border-style:dashed}

.ll-svg path{fill:none;stroke:var(--ink-2);stroke-width:1.5}
.ll-svg .hd{fill:var(--ink-2);stroke:none}
.ll-svg .hit path{stroke:var(--mark);stroke-width:2}
.ll-svg .hit .hd{fill:var(--mark)}
.ll-svg .probe path{stroke:var(--probe);stroke-width:2}
.ll-svg .probe .hd{fill:var(--probe)}
.ll-svg .ok path{stroke:var(--ok)}
.ll-svg .ok .hd{fill:var(--ok)}
.ll-svg .stale path{stroke:var(--ink-4);stroke-dasharray:4 3}
.ll-svg .stale .hd{fill:var(--ink-4)}

.ll .ptr{z-index:6;transition:transform calc(var(--dur) * .6) cubic-bezier(.25,1,.5,1), opacity .2s}
.ll .ptr.up svg{visibility:hidden} /* stacked label: only the lowest one carries the tip */
.ll .ptr.hot{color:var(--mark)}

@media (max-width:520px){
  .ll{--ll-v:28px;--ll-s:14px;--ll-h:36px;--ll-gap:20px;--ll-line:56px;padding-left:18px}
  .ll-node .v{font-size:var(--fs-label)}
}
@media (prefers-reduced-motion: reduce){
  .ll .ptr{transition:opacity .2s}
}
