/* knowledgebases.html — rules the flat system does not provide */

/* The pipeline is drawn at 380 x 440 and must not stretch to the column. */
.pg-kb-pipe { max-width: 380px; }
/* Centre the drawn-size SVG in the panel; flat.css frames size by content only. */
.pg-kb-pipe-frame { display: flex; align-items: flex-start; justify-content: center; }
/* Below ~430px the frame is narrower than the drawing; --viz-pin makes viz-frame--wide scroll it
   instead of shrinking the 11.5px labels under the type floor — the same trade
   architecture.html accepts for cert-knowledge-graph-inspector at narrow widths. */
.pg-kb-pipe-frame { --viz-pin: 380px; }
/* The drawing stays in view while the reader moves down the six rows. At the 70px stage pitch
   the drawing (440 viewBox units) is shorter than the 616px row list at 1280, so the sticky has
   real travel: an instant-scroll sweep through the section shows the frame pin at top:88px for
   ~150px of scrollY while the list keeps moving, a 144px delta (frameHeight 472 vs listHeight
   616) — not the single 24px clamp sample the previous pitch produced. Re-run the sweep after
   touching either the pitch or .hue-rows before trusting a single sample again. */
@media (min-width: 801px) { .pg-kb-pipe-frame { position: sticky; top: calc(var(--nav-h) + var(--sp-4)); } }

/* Linked hover: a row lights its stage in the drawing and vice versa (knowledgebases.js). */
.pg-kb-stage { cursor: pointer; transition: opacity 0.18s var(--ease); outline: 0; }
.pg-kb-stage rect:first-child { transition: stroke-width 0.18s var(--ease), stroke 0.18s var(--ease); }
.pg-kb-stage .pg-kb-dot { transition: fill 0.18s var(--ease), stroke 0.18s var(--ease); }
/* The step number is the callout's SVG twin (DESIGN.md Callout Rule): same disc, same hue, as
   the row marker below, so the lit end must recolour the same way — bronze on hover/focus. */
.pg-kb-stage .pg-kb-num { transition: fill 0.18s var(--ease); }
.pg-kb-stage.is-dim { opacity: 0.35; }
.pg-kb-stage.is-hot rect:first-child { stroke-width: 3; stroke: var(--green); }
.pg-kb-stage:focus-visible rect:first-child { stroke: var(--green); stroke-width: 3; }
.pg-kb-stage.is-hot .pg-kb-dot,
.pg-kb-stage:focus-visible .pg-kb-dot { fill: var(--yellow); stroke: var(--yellow); }
.pg-kb-stage.is-hot .pg-kb-num,
.pg-kb-stage:focus-visible .pg-kb-num { fill: var(--yellow); }
.pg-kb-steps-list .hue-row { cursor: pointer; outline: 0; transition: opacity 0.15s var(--ease), background 0.15s var(--ease); }
.pg-kb-steps-list .hue-row.is-dim { opacity: 0.45; }
.pg-kb-steps-list .hue-row.is-hot { background: color-mix(in srgb, var(--bg-tint), var(--green) 8%); }

/* The one moving mark: a bronze token running the route, the flat replacement for the old
   floating hero panel's drift. Bronze is the highlight hue (DESIGN.md colour grammar). */
.pg-kb-flow { animation: pg-kb-flow 2.4s linear infinite; }
@keyframes pg-kb-flow { to { stroke-dashoffset: -48; } }

/* The screenshot needs a positioning context for its annotation layer; flat.css has none.
   It is also the sizing context for the pin-hiding rule below: the hero image scales with
   its column rather than snapping at a viewport breakpoint, so the decision to show the
   chips has to read the shot's own rendered width, not the viewport's. */
.pg-kb-shotwrap { position: relative; display: block; container-type: inline-size; }
.pg-kb-shotwrap img { display: block; width: 100%; border-radius: var(--r-card); }
.pg-kb-pins { position: absolute; inset: 0; pointer-events: none; }
/* Each pin is sized to the dot alone and centred on --x/--y with translate(-50%,-50%), so the
   dot — not a dot+chip stack — sits on the node the coordinates were measured against. The
   chip is positioned off the dot's box, not laid out beside it in a flex stack. */
.pg-kb-pin { position: absolute; left: var(--x); top: var(--y); width: 10px; height: 10px; transform: translate(-50%, -50%); }
.pg-kb-pin--a { --x: 17.3%; --y: 53.3%; }
.pg-kb-pin--b { --x: 44.9%; --y: 42.4%; }
.pg-kb-pin--c { --x: 87.1%; --y: 50.9%; }
.pg-kb-pin--d { --x: 65%; --y: 52.5%; }
.pg-kb-pin__dot { position: absolute; inset: 0; border-radius: var(--r-pill); background: var(--paper); border: 2px solid var(--yellow); }
/* The chip clears the node box rather than sitting on it (nodes measured ~42-60% of frame
   height): below the dot for a/c/d, above it for b, whose dot sits on the node's top edge. */
.pg-kb-pin .chip { position: absolute; left: 50%; top: 26px; transform: translateX(-50%); white-space: nowrap; }
.pg-kb-pin--b .chip { top: auto; bottom: 26px; }
/* The pulse ring is the flat replacement for the old floating panel's drift: one calm mark,
   staggered so only one ring is expanding at a time. */
.pg-kb-pin__dot::after { content: ""; position: absolute; inset: -2px; border-radius: var(--r-pill); border: 2px solid var(--yellow); animation: pg-kb-ping 2.4s var(--ease) infinite; animation-delay: var(--ping-delay, 0s); }
.pg-kb-pin--b .pg-kb-pin__dot::after { --ping-delay: 0.6s; }
.pg-kb-pin--d .pg-kb-pin__dot::after { --ping-delay: 1.2s; }
.pg-kb-pin--c .pg-kb-pin__dot::after { --ping-delay: 1.8s; }
@keyframes pg-kb-ping { 0% { opacity: 0.55; transform: scale(1); } 70%, 100% { opacity: 0; transform: scale(2.4); } }
/* Hide the chips only once the shot itself is too narrow to hold them, not at a fixed viewport
   width. There are four chips now, and the binding constraint is chip d colliding with chip c
   (not the shot edge): the pair first clears at a shot width of ~467px and only reads as two
   distinct chips above ~480px, so the threshold sits at 490px to close that band with margin.
   Below that the caption on the frame carries the same facts. */
@container (max-width: 490px) { .pg-kb-pins { display: none; } }

/* Reduced motion renders the end state: the route drawn, the pins visible, nothing moving. */
@media (prefers-reduced-motion: reduce) {
  .pg-kb-flow { animation: none; stroke-dashoffset: 0; }
  .pg-kb-pin__dot::after { animation: none; opacity: 0; }
}
