/* ===========================================================
   MORPH-SLIDES DIAGRAMS: looks for the 8 kinds drawn by
   morph-viz.js + morph-viz-diagrams.js. Colours come from the
   --viz-* tokens in morph-motion.css (they follow the style's
   --fg/--bg, so light and dark styles both work).
   Place each .viz with inline left/top/width/height (or right/bottom).
   Click states use the slide's data-at and reset transition-delay,
   otherwise they would wait for the entrance delay.
   =========================================================== */
.viz { position: absolute; color: var(--viz-ink); }
.viz svg { overflow: visible; }

/* ---------- span: proportional bar (time, budget) ---------- */
.viz .bar { position: absolute; left: 0; right: 0; top: calc(50% - var(--bar-h, 180px) / 2); height: var(--bar-h, 180px); }
.viz .seg { position: absolute; top: 0; bottom: 0; background: var(--viz-ink); color: var(--viz-paper); border-right: 3px solid var(--viz-paper); display: grid; place-items: center; }
.viz .seg b { position: relative; font: 400 72px/1 var(--font-display); }
.viz .seg .morph-src { position: absolute; inset: 0; }
.slide:not([data-at="0"]) .viz .seg.hot { background: var(--viz-hot); color: #fff; transition: background .4s; transition-delay: 0s !important; }
.viz .note { position: absolute; display: flex; flex-direction: column; gap: 6px; font-size: 31px; line-height: 1.25; padding-left: 16px; border-left: 1.5px solid var(--viz-ink); }
.viz .note.flip { padding: 0 16px 0 0; border-left: 0; border-right: 1.5px solid var(--viz-ink); text-align: right; }
.viz .note.above { bottom: calc(50% + var(--bar-h, 180px) / 2); padding-bottom: 24px; }
.viz .note.below { top: calc(50% + var(--bar-h, 180px) / 2); padding-top: 24px; }
.viz .note .mono { font: 500 22px/1.2 var(--viz-mono); letter-spacing: .04em; color: var(--viz-muted); }

/* ---------- donut ---------- */
.viz .arc { fill: none; stroke: var(--viz-ink); stroke-width: 80; stroke-dasharray: 0 100; stroke-dashoffset: var(--off); transform: rotate(-90deg); transform-origin: center; transform-box: fill-box; transition: stroke-dasharray 1s cubic-bezier(.6, 0, .2, 1); }
.viz .arc:nth-child(4n+3) { stroke: color-mix(in srgb, var(--viz-ink) 65%, var(--viz-paper)); }
.slide.active .viz .arc { stroke-dasharray: var(--v) 100; transition-delay: calc(var(--reveal-base) + var(--d) * 1s); }
.viz .arc-n { fill: var(--viz-ink); font: 500 28px/1 var(--viz-mono); text-anchor: middle; dominant-baseline: middle; }

/* ---------- plan: outline + dimension chains ---------- */
.viz .wall { fill: var(--viz-fill); stroke: var(--viz-ink); stroke-width: 3; }
.viz .part { fill: var(--viz-ink); }
.viz .dim { fill: none; stroke: var(--viz-ink); stroke-width: 2; }
.viz .tick { fill: none; stroke: var(--viz-ink); stroke-width: 2.5; }
.viz :is(.dim, .tick).hot { stroke: var(--viz-hot); }
.viz .lens circle { fill: var(--viz-paper); stroke: var(--viz-hot); stroke-width: 3; }
.viz .lens :is(line, path) { stroke: var(--viz-hot); stroke-width: 3; }
.viz .lens text { fill: var(--viz-hot); font: 600 24px/1 var(--viz-mono); text-anchor: middle; }

/* ---------- gather: pieces fly to the centre ---------- */
.viz .piece { position: absolute; width: 64px; height: 64px; border: 2px solid currentColor; display: grid; place-items: center; font: 500 20px/1 var(--viz-mono); }

/* ---------- matrix ---------- */
.viz[data-viz="matrix"] { display: grid; align-items: stretch; }
.mx-col, .mx-row { font: 400 50px/1.1 var(--font-display); display: flex; align-items: center; }
.mx-col { justify-content: center; padding: 0 0 22px; border-bottom: 2.5px solid var(--viz-ink); }
.mx-row { padding: 0 24px 0 0; border-right: 2.5px solid var(--viz-ink); }
.mx-row, .mx-cell { min-height: 186px; border-bottom: 1.5px solid var(--viz-faint); }
.mx-cell { display: grid; place-items: center; text-align: center; padding: 18px 26px; font: 500 31px/1.35 var(--viz-mono); position: relative; transition: background-color .4s, color .4s, opacity .5s, transform .9s var(--morph-ease); }
.slide:not([data-at="0"]) .viz .mx-cell.hot { background: var(--viz-ink); color: var(--viz-paper); transition-delay: 0s !important; }
.slide:not([data-at="0"]) .viz .mx-cell:not(.hot) { opacity: .45; transition-delay: 0s !important; }

/* ---------- network ---------- */
.viz[data-viz="network"] svg, .viz[data-viz="funnel"] svg { position: absolute; inset: 0; }
.viz .edge { fill: none; stroke: var(--viz-ink); stroke-width: 2; transition: stroke-dashoffset 1.3s cubic-bezier(.6, 0, .2, 1), stroke-width .4s, opacity .4s; }
.viz .edge.off { stroke-dasharray: 6 8; stroke-dashoffset: 0; opacity: .5; }
.viz .nd { position: absolute; width: 330px; margin: -55px 0 0 -165px; padding: 14px 20px; background: var(--viz-paper); border: 2px solid var(--viz-ink); display: flex; flex-direction: column; gap: 4px; transition: opacity .5s, background-color .4s, color .4s, transform .9s var(--morph-ease); }
.viz .nd b { font: 600 28px/1.1 var(--viz-mono); }
.viz .nd span { font-size: 20px; line-height: 1.3; color: var(--viz-muted); }
.viz .nd.off { border-style: dashed; color: var(--viz-muted); }
.viz .hub { position: absolute; width: 190px; height: 190px; margin: -95px 0 0 -95px; border-radius: 50%; background: var(--viz-ink); color: var(--viz-paper); display: grid; place-items: center; text-align: center; font: 400 44px/1 var(--font-display); }
.slide:not([data-at="0"]) .viz .nd:not(.on) { opacity: .3; transition-delay: 0s !important; }
.slide:not([data-at="0"]) .viz .nd.on { background: var(--viz-ink); color: var(--viz-paper); transition-delay: 0s !important; }
.slide:not([data-at="0"]) .viz .nd.on span { color: var(--viz-paper); }
.slide:not([data-at="0"]) .viz .edge.on { stroke-width: 6; }
.slide:not([data-at="0"]) .viz .edge:not(.on) { opacity: .25; }

/* ---------- funnel ---------- */
.viz .ly { fill: var(--viz-fill); stroke: var(--viz-ink); stroke-width: 2.5; }
.viz .ly:last-child { fill: var(--viz-ink); }
.viz .ly-t { position: absolute; left: 0; right: 0; transform: translateY(-50%); text-align: center; font: 400 36px/1.1 var(--font-display); }
.viz .ly-t:nth-last-of-type(1) { color: var(--viz-paper); }
.viz .dot { position: absolute; width: 36px; height: 36px; margin-left: -18px; border-radius: 50%; background: var(--viz-paper); border: 3px solid var(--viz-ink); }
.viz .dot.caught { background: var(--viz-hot); border-color: var(--viz-hot); }
.slide.active .viz .dot { transition-timing-function: ease, cubic-bezier(.55, 0, 1, .45), ease, ease; transition-duration: .3s, .8s; }

/* ---------- compare: the second panel wipes over the first on click ---------- */
@property --cut { syntax: '<percentage>'; inherits: true; initial-value: 100%; }
.viz[data-viz="compare"] { --cut: 100%; transition: --cut 1.1s cubic-bezier(.7, 0, .2, 1), opacity .5s ease, transform .9s var(--morph-ease); }
.slide:not([data-at="0"]) .viz[data-viz="compare"] { --cut: 0%; transition-delay: 0s !important; }
.viz .cmp-a, .viz .cmp-b { position: absolute; inset: 0; }
.viz .cmp-b { clip-path: inset(0 0 0 var(--cut)); }
.viz .cmp-knob { position: absolute; top: -18px; bottom: -18px; left: var(--cut); width: 6px; margin-left: -3px; background: var(--viz-hot); opacity: 0; }
.viz .cmp-knob::after { content: "⇆"; position: absolute; top: 50%; left: 50%; width: 64px; height: 64px; margin: -32px 0 0 -32px; border-radius: 50%; background: var(--viz-hot); color: #fff; display: grid; place-items: center; font: 600 30px/1 var(--font-body); }
.slide:not([data-at="0"]) .viz .cmp-knob { animation: sf-knob 1.1s cubic-bezier(.7, 0, .2, 1); }
@keyframes sf-knob { 0%, 100% { opacity: 0; } 10%, 85% { opacity: 1; } }
.deck-stage.auditing .viz[data-viz="compare"] { --cut: 0%; }

/* filled parts: bold/emphasis inside follow the part's own text colour (styles colour <b> for body text,
   which turned a segment's number dark on dark) */
.slide .viz :is(.seg, .mx-cell.hot, .nd.on, .cmp-panel.solid) :is(b, strong, em, i, code) { color: inherit; }
