/* ============================================================
   MEDSY — DATA-VIZ INTERACTION LAYER
   One vocabulary for every chart & diagram: a shared tooltip
   chip, hot/dim sibling focus, keyboard navigation, and
   reveal-once entrances. Base styles are always the FINAL
   state — `.viz.in` only REPLAYS the entrance from zero when
   the chart first scrolls into view with motion allowed — so
   print, PDF export, no-JS and reduced-motion always show
   finished charts.
   ============================================================ */

/* ---------- wrapper ---------- */
.viz{position:relative;outline-offset:4px}
.viz[tabindex]{cursor:default;border-radius:var(--r-sm)}
.viz-inline{display:inline-block;vertical-align:middle}

/* visually-hidden live region for keyboard announcements */
.viz-live{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}

/* ---------- tooltip chip ---------- */
.viz-tip{position:absolute;z-index:70;pointer-events:none;min-width:84px;max-width:min(260px,92%);
  background:var(--surface-inverse);color:var(--text-on-inverse);border-radius:11px;padding:9px 12px 10px;
  box-shadow:var(--shadow-lg);opacity:0;visibility:hidden;
  transform:translate(-50%,calc(-100% - 7px)) scale(.9);transform-origin:bottom center;
  transition: opacity var(--dur-hover) var(--ease-standard),transform var(--dur-control) var(--ease-spring),visibility var(--dur-hover) step-end}
/* hidden, not just transparent: an opacity-0 chip keeps its stale label in the
   accessibility tree and in find-in-page. Matches every other popover surface. */
.viz-tip.show{opacity:1;visibility:visible;transition-timing-function:var(--ease-standard),var(--ease-spring),step-start;transform:translate(-50%,calc(-100% - 12px)) scale(1)}
.viz-tip.below{transform:translate(-50%,15px) scale(.9);transform-origin:top center}
.viz-tip.below.show{transform:translate(-50%,12px) scale(1)}
.viz-tip::after{content:"";position:absolute;left:calc(50% - var(--vt-shift,0px));top:100%;transform:translateX(-50%);
  border:5px solid transparent;border-top-color:var(--surface-inverse)}
.viz-tip.below::after{top:auto;bottom:100%;border-top-color:transparent;border-bottom-color:var(--surface-inverse)}
.vt-k{display:flex;align-items:center;gap:6px;font-family:var(--f-caps);font-size:var(--fs-micro);font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;opacity:.75;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vt-dot{width:8px;height:8px;border-radius:3px;flex:none;box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--text-on-inverse) 25%,transparent)}
.vt-v{font-family:var(--f-display);font-weight:800;font-size:1.08rem;line-height:1.3;letter-spacing:-.01em;white-space:nowrap}
.vt-s{font-size:.72rem;line-height:1.4;opacity:.82}
.vt-rows{display:grid;gap:3px;margin-top:6px;padding-top:6px;border-top:1px solid color-mix(in srgb,var(--text-on-inverse) 18%,transparent)}
.vt-row{display:flex;align-items:center;gap:7px;font-size:.74rem;line-height:1.3;white-space:nowrap}
.vt-row .vt-rl{opacity:.8;overflow:hidden;text-overflow:ellipsis}
.vt-row strong{margin-left:auto;padding-left:14px;font-variant-numeric:tabular-nums;font-weight:700;font-size:.72rem}

/* ---------- hot / dim (sibling softening) ---------- */
.viz [data-viz-d]{transition: opacity var(--dur-control) var(--ease-standard),filter var(--dur-control) var(--ease-standard)}
.viz.has-hot [data-viz-d]{opacity:.4;filter:saturate(.75)}
.viz.has-hot [data-viz-d].hot{opacity:1;filter:none}

/* legend chips join the hot/dim conversation */
.viz .v-chart-legend .lg{transition: opacity var(--dur-control) var(--ease-standard);cursor:default}
.viz.has-hot .v-chart-legend .lg{opacity:.45}
.viz.has-hot .v-chart-legend .lg.hot{opacity:1}

/* ---------- entrance keyframes (replay-from-zero) ---------- */
@keyframes vizGrowY{from{transform:scaleY(0)}}
@keyframes vizGrowX{from{transform:scaleX(0)}}
@keyframes vizPop{from{opacity:0;transform:scale(0)}}
@keyframes vizFade{from{opacity:0}}
@keyframes vizRise{from{opacity:0;transform:translateY(12px)}}
@keyframes vizDraw{from{stroke-dashoffset:1}}
@keyframes vizArc{from{stroke-dashoffset:var(--c)}}
@keyframes vizSweep{from{stroke-dashoffset:var(--vz-len)}}
@keyframes vizPieIn{from{opacity:0;transform:scale(.82) rotate(-7deg)}}
@keyframes vizRadarIn{from{opacity:0;transform:scale(.55)}}
@keyframes vizBubbleIn{from{opacity:0;transform:translate(-50%,-50%) scale(.3)}}

/* ---------- BAR CHART ---------- */
.viz.in .v-bar{animation: vizGrowY var(--dur-entrance) var(--ease-spring) both;transform-origin:bottom;animation-delay:calc(var(--vzi,0)*45ms)}
.viz.in .v-bar-val{animation: vizFade var(--dur-control) var(--ease-standard) both;animation-delay:calc(var(--vzi,0)*45ms + .32s)}
.v-bar-col.hot .v-bar{filter:brightness(1.07) saturate(1.05)}
.v-bar-col.hot .v-bar-label{color:var(--forest);font-weight:600}
.v-bar-label{transition: color var(--dur-hover) var(--ease-standard)}
/* CSS-only fallback so plain-HTML charts (templates) answer the cursor too */
.v-bar{transition: filter var(--dur-hover) var(--ease-standard)}
.v-bar-col:hover .v-bar{filter:brightness(1.07) saturate(1.05)}
.v-bar-col:hover .v-bar-label{color:var(--forest);font-weight:600}

/* ---------- HORIZONTAL BARS ---------- */
.viz.in .v-hbar-fill{animation: vizGrowX var(--dur-entrance) var(--ease-standard) both;transform-origin:left;animation-delay:calc(var(--vzi,0)*55ms)}
.viz.in .v-hbar-val{animation: vizFade var(--dur-control) var(--ease-standard) both;animation-delay:calc(var(--vzi,0)*55ms + .3s)}
.v-hbar-row.hot .v-hbar-fill{filter:brightness(1.08)}
.v-hbar-row.hot .v-hbar-label{color:var(--forest)}
.v-hbar-label{transition: color var(--dur-hover) var(--ease-standard)}
.v-hbar-fill{transition: filter var(--dur-hover) var(--ease-standard)}
.v-hbar-row:hover .v-hbar-fill{filter:brightness(1.08)}
.v-hbar-row:hover .v-hbar-label{color:var(--forest)}

/* ---------- LINE CHART ---------- */
.viz .v-draw{stroke-dasharray:1 1;stroke-dashoffset:0}
.viz.in .v-draw{animation: vizDraw var(--dur-reveal) var(--ease-standard) both}
.viz.in .v-line-area{animation: vizFade var(--dur-slower) var(--ease-standard) .3s both}
.viz.in .v-line-dot{animation: vizPop var(--dur-control) var(--ease-spring) both;animation-delay:calc(.15s + var(--vzi,0)*55ms)}
.v-line-dot{transform-box:fill-box;transform-origin:center;transition: transform var(--dur-control) var(--ease-spring),stroke-width var(--dur-hover) var(--ease-standard)}
.v-line-dot.hot{transform:scale(1.55)}
.viz.in .v-line-xlabel{animation: vizFade var(--dur-overlay) var(--ease-standard) .35s both}
.viz-xhair{stroke:var(--forest-300);stroke-width:1.2;stroke-dasharray:4 4;opacity:.85}

/* ---------- SPARKLINE ---------- */
.viz.in .v-sparkline-area{animation: vizFade var(--dur-entrance) var(--ease-standard) .22s both}
.viz.in .v-sparkline-dot{animation: vizPop var(--dur-control) var(--ease-spring) both;animation-delay:.5s;transform-box:fill-box;transform-origin:center}
.v-spark-cursor{transition: opacity var(--dur-hover) var(--ease-standard)}

/* ---------- SCATTER ---------- */
.v-scatter-pt{transform-box:fill-box;transform-origin:center;transition: transform var(--dur-control) var(--ease-spring),opacity var(--dur-control) var(--ease-standard),filter var(--dur-control) var(--ease-standard)}
.viz.in .v-scatter-pt{animation: vizPop var(--dur-overlay) var(--ease-spring) both;animation-delay:calc(var(--vzi,0)*35ms)}
.v-scatter-pt.hot{transform:scale(1.45)}

/* ---------- PIE ---------- */
.viz.in .v-pie-g{animation: vizPieIn var(--dur-entrance) var(--ease-spring) both;transform-box:view-box;transform-origin:center}
.v-pie-slice{transition: transform var(--dur-control) var(--ease-spring),opacity var(--dur-control) var(--ease-standard),filter var(--dur-control) var(--ease-standard)}
.v-pie-slice.hot{transform:translate(var(--vz-tx,0px),var(--vz-ty,0px))}

/* ---------- DONUT / PROGRESS RING / GAUGE ---------- */
.viz.in .arc{animation: vizArc var(--dur-reveal) var(--ease-standard) both}
.viz.in .v-arc-tipdot{animation: vizFade var(--dur-control) var(--ease-standard) .7s both}
.viz.in .v-gauge-fill{animation: vizSweep var(--dur-reveal) var(--ease-standard) both}
.viz-ring .arc,.viz-ring .v-gauge-fill{transition: filter var(--dur-hover) var(--ease-standard)}
.viz-ring:hover .arc,.viz-ring:hover .v-gauge-fill{filter:brightness(1.06)}

/* ---------- WAFFLE ---------- */
.viz.in .v-waffle-cell.on{animation: vizPop var(--dur-control) var(--ease-spring) both;animation-delay:calc(var(--vzi,0)*9ms)}

/* ---------- FUNNEL ---------- */
.v-funnel-row [data-viz-d]{min-width:0}
.viz.in .v-funnel-bar{animation: vizGrowX var(--dur-entrance) var(--ease-spring) both;transform-origin:center;animation-delay:calc(var(--vzi,0)*70ms)}
.v-funnel-bar{transition: filter var(--dur-hover) var(--ease-standard),box-shadow var(--dur-hover) var(--ease-standard)}
.v-funnel-row.hot .v-funnel-bar,.v-funnel-row:hover .v-funnel-bar{filter:brightness(1.07)}
.v-funnel-row.hot .v-funnel-conv,.v-funnel-row:hover .v-funnel-conv{color:var(--text-strong)}
.v-funnel-conv{transition: color var(--dur-hover) var(--ease-standard)}

/* ---------- RADAR ---------- */
.viz.in .v-radar-poly{animation: vizRadarIn var(--dur-entrance) var(--ease-spring) both}
.viz.in .v-radar-dot{animation: vizPop var(--dur-control) var(--ease-spring) both;animation-delay:calc(.22s + var(--vzi,0)*40ms)}
.v-radar-dot{transform-box:fill-box;transform-origin:center;transition: transform var(--dur-control) var(--ease-spring)}
.v-radar-dot.hot{transform:scale(1.5)}
.viz.in .v-radar-comp{animation: vizFade var(--dur-entrance) var(--ease-standard) .4s both}
.radar-lbl{transition: fill var(--dur-hover) var(--ease-standard)}
.radar-lbl.hot{fill:var(--forest);font-weight:700}

/* ---------- HEAT MAP ---------- */
.viz.in .dgm-heat-cell{animation: vizFade var(--dur-overlay) var(--ease-standard) both;animation-delay:calc(var(--vzi,0)*14ms)}
.dgm-heat-cell{transition: transform var(--dur-hover) var(--ease-spring),box-shadow var(--dur-hover) var(--ease-standard),opacity var(--dur-control) var(--ease-standard),filter var(--dur-control) var(--ease-standard)}
.viz .dgm-heat-cell.hot,.dgm-heat-cell:hover{transform:scale(1.14);box-shadow:var(--shadow-md);z-index:2}
.viz.has-hot .dgm-heat-cell:not(.hot){opacity:.45;filter:saturate(.8)}
.dgm-heat-row-label,.dgm-heat-col-label{transition: color var(--dur-hover) var(--ease-standard)}
.dgm-heat-row-label.hot,.dgm-heat-col-label.hot{color:var(--forest);font-weight:700}

/* ---------- FLOWCHART / SWIMLANE ---------- */
.viz.in .dgm-flow > .dgm-node,
.viz.in .dgm-flow > .dgm-diamond,
.viz.in .dgm-flow .dgm-branch .dgm-node,
.viz.in .dgm-flow .dgm-branch .dgm-diamond{animation: vizRise var(--dur-overlay) var(--ease-standard) both;animation-delay:calc(var(--vzi,0)*70ms)}
.dgm-flow .dgm-node:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm);border-color:var(--line-mint)}
.dgm-flow .dgm-node.is-io:hover{transform:skewX(-11deg) translateY(-2px)}
.dgm-diamond{transition: transform var(--dur-control) var(--ease-spring),filter var(--dur-control) var(--ease-standard)}
.dgm-diamond:hover{transform:translateY(-2px)}
.dgm-link{transition: color var(--dur-control) var(--ease-standard)}
.dgm-node:hover + .dgm-link,.dgm-diamond:hover + .dgm-link,
.dgm-link:has(+ .dgm-node:hover),.dgm-link:has(+ .dgm-diamond:hover){color:var(--forest)}

.viz.in .dgm-swim-cell .dgm-node,
.viz.in .dgm-lane-track .dgm-node{animation: vizRise var(--dur-overlay) var(--ease-standard) both;animation-delay:calc(var(--vzi,0)*55ms)}
.dgm-swim-cell .dgm-node{transition: transform var(--dur-control) var(--ease-spring),box-shadow var(--dur-control) var(--ease-standard),border-color var(--dur-control) var(--ease-standard),opacity var(--dur-control) var(--ease-standard)}
.dgm-swim-cell .dgm-node:hover{transform:translateY(-2px);box-shadow:var(--shadow-sm)}
.dgm-swim-cell .dgm-node.is-io:hover{transform:skewX(-11deg) translateY(-2px)}
.dgm-swim-links path{transition: opacity var(--dur-control) var(--ease-standard),stroke-width var(--dur-hover) var(--ease-standard)}
.dgm-swim.has-hot .dgm-swim-links path{opacity:.28}
.dgm-swim.has-hot .dgm-swim-links path.hot{opacity:1;stroke-width:3}
.dgm-swim.has-hot .dgm-swim-cell .dgm-node{opacity:.5}
.dgm-swim.has-hot .dgm-swim-cell .dgm-node.hot{opacity:1;box-shadow:var(--shadow-sm);border-color:var(--line-mint)}

/* ---------- MIND MAP ---------- */
.viz.in .dgm-branch-card{animation: vizRise var(--dur-overlay) var(--ease-standard) both;animation-delay:calc(.1s + var(--vzi,0)*60ms)}
.viz.in .dgm-mind-core{animation: vizPop var(--dur-entrance) var(--ease-spring) both}
.viz.in .dgm-mind-links path{animation: vizFade var(--dur-overlay) var(--ease-standard) both;animation-delay:calc(.15s + var(--vzi,0)*60ms)}
.dgm-mind-links path{transition: opacity var(--dur-control) var(--ease-standard),stroke-width var(--dur-hover) var(--ease-standard)}
.dgm-mind.has-hot .dgm-mind-links path{opacity:.22}
.dgm-mind.has-hot .dgm-mind-links path.hot{opacity:1;stroke-width:3.5}
.dgm-branch-card{transition: transform var(--dur-overlay) var(--ease-spring),box-shadow var(--dur-overlay) var(--ease-standard),opacity var(--dur-control) var(--ease-standard)}
.dgm-mind.has-hot .dgm-branch-card{opacity:.5}
.dgm-mind.has-hot .dgm-branch-card.hot{opacity:1;transform:translateY(-2px);box-shadow:var(--shadow-sm)}

/* ---------- BUBBLE MAP ---------- */
.viz.in .dgm-bubble-core{animation: vizBubbleIn var(--dur-entrance) var(--ease-spring) both}
.viz.in .dgm-bubble-node{animation: vizBubbleIn var(--dur-overlay) var(--ease-spring) both;animation-delay:calc(.12s + var(--vzi,0)*55ms)}
.viz.in .dgm-bubble svg .lk{animation: vizFade var(--dur-overlay) var(--ease-standard) both;animation-delay:calc(.1s + var(--vzi,0)*55ms)}
.dgm-bubble svg .lk{transition: opacity var(--dur-control) var(--ease-standard),stroke-width var(--dur-hover) var(--ease-standard)}
.dgm-bubble svg .tip{transition: opacity var(--dur-control) var(--ease-standard)}
.dgm-bubble.has-hot .lk{opacity:.3}
.dgm-bubble.has-hot .lk.hot{opacity:1;stroke-width:3;stroke:var(--mint)}
.dgm-bubble.has-hot .tip:not(.hot){opacity:.3}
.dgm-bubble-node{transition: transform var(--dur-control) var(--ease-spring),box-shadow var(--dur-control) var(--ease-standard),border-color var(--dur-control),opacity var(--dur-control) var(--ease-standard)}
.dgm-bubble.has-hot .dgm-bubble-node:not(:hover){opacity:.55}

/* ---------- MATRIX / TIMELINE MAP / BRACE ---------- */
.viz.in .dgm-quad{animation: vizFade var(--dur-overlay) var(--ease-standard) both;animation-delay:calc(var(--vzi,0)*70ms)}
.viz.in .dgm-tmap-node{animation: vizRise var(--dur-entrance) var(--ease-standard) both;animation-delay:calc(var(--vzi,0)*80ms)}
.viz.in .dgm-brace-part{animation: vizRise var(--dur-overlay) var(--ease-standard) both;animation-delay:calc(.08s + var(--vzi,0)*70ms)}
.viz.in .dgm-brace-whole,.viz.in .dgm-brace-arm{animation: vizFade var(--dur-overlay) var(--ease-standard) both}
.dgm-brace-part-label{transition: transform var(--dur-control) var(--ease-spring),box-shadow var(--dur-control) var(--ease-standard),border-color var(--dur-control) var(--ease-standard)}
.dgm-brace-part:hover > .dgm-brace-part-label{transform:translateX(2px);box-shadow:var(--shadow-sm);border-color:var(--line-mint)}
.dgm-brace-arm,.dgm-brace-sub{transition: color var(--dur-control) var(--ease-standard)}
.dgm-brace:hover > .dgm-brace-arm{color:var(--forest)}
.dgm-brace-part:hover .dgm-brace-sub{color:var(--forest-300)}

/* ---------- print: never catch a chart mid-entrance ---------- */
@media print{
  .viz,.viz *{animation: none !important}
  .viz-tip{display:none !important}
}

/* ---------- reduced motion: hovers stay, movement stops ---------- */
@media (prefers-reduced-motion: reduce){
  .v-bar,.v-hbar-fill,.v-funnel-bar,.dgm-heat-cell,.v-line-dot,.v-scatter-pt,.v-pie-slice,
  .v-radar-dot,.dgm-branch-card,.dgm-bubble-node,.dgm-swim-cell .dgm-node{transition: none!important}
  .dgm-heat-cell:hover{transform:none}
}

/* ---------- AREA / STACKED BAR ---------- */
.v-areachart,.v-sbarchart{position:relative;display:inline-block;max-width:100%}
.v-chart-legend{display:flex;flex-wrap:wrap;gap:14px;margin-top:10px}
.v-cl-item{display:inline-flex;align-items:center;gap:7px;font-family:var(--f-caps);font-size:var(--fs-micro);letter-spacing:.06em;color:var(--ink-soft)}
.v-cl-dot{width:9px;height:9px;border-radius:3px}
.viz.in .v-area-layer{animation: v-fadein-soft var(--dur-slower) var(--ease-standard) both}
@keyframes v-fadein-soft{from{opacity:0}to{opacity:1}}
.v-sbar-seg{transform-box:fill-box;transform-origin:bottom}
.viz.in .v-sbar-seg{animation: v-seg-rise var(--dur-entrance) var(--ease-standard) both}
@keyframes v-seg-rise{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@media (prefers-reduced-motion: reduce){.viz.in .v-area-layer,.viz.in .v-sbar-seg{animation: none}}


/* ============================================================
   PRESS STATES — chart marks — tap gives the same read as hover
   Hover is not feedback on a touch screen, and a control that only
   responds to hover feels dead under a finger. Every interactive
   surface here answers a press with the same vocabulary the buttons
   use: small controls sink (translateY(1px) scale(.97)), lifted
   cards press back through their lift, and data cells dip in place.
   Presses are instant by design — no transition — so the response
   lands on touch-down rather than easing in after it.
   ============================================================ */
.v-bar-col:active .v-bar,.v-funnel-row:active .v-funnel-bar{filter:brightness(.94) saturate(1.08)}
.v-hbar-row:active .v-hbar-fill{filter:brightness(.94) saturate(1.08)}
.viz-ring:active .arc,.viz-ring:active .v-gauge-fill{filter:brightness(.94) saturate(1.08)}
.dgm-heat-cell:active{transform:scale(.88)}
