/* ============================================
   NOVARA — Learning Path page
   ============================================ */

.path-hero {
  position: relative;
  padding: 160px var(--pad-page) 60px;
  background:
    radial-gradient(circle at 70% 30%, rgba(31,135,114,0.15) 0%, transparent 55%),
    radial-gradient(circle at 15% 75%, rgba(201,162,74,0.1) 0%, transparent 55%),
    var(--night);
  overflow: hidden;
}
.path-hero canvas {
  position: absolute; inset: 0; z-index: 0; pointer-events: none;
}
.path-hero-inner {
  position: relative;
  z-index: 2;
  max-width: var(--maxw);
  margin: 0 auto;
}

.path-h1 {
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 6vw, 5.5rem);
  font-weight: 300;
  letter-spacing: -0.03em;
  line-height: 0.98;
  margin-bottom: 28px;
}
.path-h1 .em {
  font-style: italic;
  font-family: var(--font-stylish);
  background: var(--grad-gold);
  -webkit-background-clip: text;
  background-clip: text;
  -webkit-text-fill-color: transparent;
}
.path-intro {
  max-width: 620px;
  font-family: var(--font-small);
  font-size: 1.08rem;
  line-height: 1.7;
  color: var(--cream-dim);
  margin-bottom: 40px;
}

.path-search {
  position: relative;
  max-width: 620px;
  margin-bottom: 24px;
}
.path-search input {
  width: 100%;
  padding: 22px 56px 22px 24px;
  background: rgba(255,255,255,0.04);
  border: 1px solid rgba(255,255,255,0.15);
  border-radius: 100px;
  color: var(--cream);
  font-family: var(--font-small);
  font-size: 1rem;
  outline: none;
  cursor: none;
  transition: border-color 0.4s, background 0.4s;
}
.path-search input:focus {
  border-color: var(--gold-warm);
  background: rgba(201,162,74,0.06);
}
.path-search input::placeholder { color: var(--cream-faint); }
.path-search .icon {
  position: absolute;
  right: 22px; top: 50%;
  transform: translateY(-50%);
  color: var(--gold-warm);
  font-size: 1.2rem;
  pointer-events: none;
}

.path-chips {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
  margin-bottom: 8px;
}
.path-chip {
  padding: 10px 18px;
  border-radius: 100px;
  border: 1px solid rgba(255,255,255,0.18);
  font-family: var(--font-small);
  font-size: 0.85rem;
  background: transparent;
  color: var(--cream-dim);
  cursor: none;
  transition: all 0.3s;
}
.path-chip:hover { border-color: var(--gold-warm); color: var(--gold-warm); }
.path-chip.is-active {
  background: var(--gold-warm);
  border-color: var(--gold-warm);
  color: var(--forest-deep);
  font-weight: 500;
}

/* Graph area */
.path-graph-section {
  position: relative;
  background: linear-gradient(180deg, var(--night) 0%, var(--forest-deep) 100%);
  padding: 80px var(--pad-page) 140px;
  overflow: hidden;
}
.path-graph-wrap {
  position: relative;
  max-width: var(--maxw);
  margin: 0 auto;
  min-height: 580px;
  background:
    radial-gradient(circle at 50% 50%, rgba(31,135,114,0.08) 0%, transparent 70%);
}
.path-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 460px;
  font-family: var(--font-stylish);
  font-style: italic;
  font-size: 1.2rem;
  color: var(--cream-faint);
  text-align: center;
}

#path-svg {
  width: 100%;
  height: 580px;
  display: block;
}
#path-svg .edge {
  fill: none;
  stroke: var(--gold-warm);
  stroke-width: 1.2;
  stroke-dasharray: 6 6;
  opacity: 0;
  animation: edge-in 0.8s var(--ease-out) forwards, dash-flow 3s linear infinite;
}
#path-svg .edge.is-vert {
  stroke: var(--emerald);
}
@keyframes edge-in {
  from { opacity: 0; }
  to { opacity: 0.65; }
}
@keyframes dash-flow {
  to { stroke-dashoffset: -100; }
}

#path-svg .node-bg {
  fill: rgba(255,255,255,0.04);
  stroke: rgba(255,255,255,0.18);
  stroke-width: 1.2;
  transition: fill 0.4s, stroke 0.4s;
}
#path-svg .node-group:hover .node-bg {
  fill: rgba(201,162,74,0.12);
  stroke: var(--gold-warm);
}
#path-svg .node-group .node-ring {
  fill: none;
  stroke: var(--gold-warm);
  stroke-width: 1;
  opacity: 0.3;
  animation: ring-pulse 3s ease-in-out infinite;
}
@keyframes ring-pulse {
  0%, 100% { opacity: 0.2; transform: scale(1); }
  50% { opacity: 0.55; transform: scale(1.15); }
}
#path-svg .node-num {
  font-family: 'Space Grotesk', monospace;
  font-size: 11px;
  fill: var(--gold-warm);
  letter-spacing: 2px;
}
#path-svg .node-title {
  font-family: 'Fraunces', serif;
  font-size: 18px;
  font-weight: 400;
  fill: var(--cream);
}
#path-svg .node-meta {
  font-family: 'Inter', sans-serif;
  font-size: 11px;
  fill: rgba(255,255,255,0.55);
}
.node-group {
  cursor: none;
  opacity: 0;
  animation: node-in 0.6s var(--ease-out) forwards;
}
/* IMPORTANT: do NOT animate `transform` here — it would override
   the SVG's transform="translate(x,y)" attribute on the <g>. */
@keyframes node-in {
  from { opacity: 0; }
  to   { opacity: 1; }
}

#path-svg .node-ring {
  transform-origin: center;
  transform-box: fill-box;
}

/* Legend */
.path-legend {
  display: flex;
  gap: 32px;
  flex-wrap: wrap;
  margin-top: 32px;
  font-family: var(--font-mono-mod);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.16em;
}
.path-legend span {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: var(--cream-dim);
}
.path-legend .dot {
  width: 10px; height: 10px; border-radius: 50%;
}
.path-legend .d1 { background: var(--emerald); }
.path-legend .d2 { background: var(--gold); }
.path-legend .d3 { background: var(--gold-warm); }
.path-legend .d4 { background: var(--cream); }

/* Tooltip */
.path-tip {
  position: fixed;
  background: var(--night);
  border: 1px solid var(--gold-warm);
  padding: 14px 18px;
  border-radius: 12px;
  max-width: 240px;
  pointer-events: none;
  z-index: 200;
  opacity: 0;
  transform: translate(-50%, -110%) scale(0.95);
  transition: opacity 0.25s, transform 0.25s var(--ease-out);
  font-family: var(--font-small);
  font-size: 0.85rem;
}
.path-tip.is-visible { opacity: 1; transform: translate(-50%, -120%) scale(1); }
.path-tip h4 { font-family: var(--font-display); font-size: 1rem; color: var(--gold-warm); margin-bottom: 6px; }

/* ============================================
   LEARNING-PATH GRAPH — ENTRANCE ANIMATIONS
   Triggered on every chip click / search hit (DOMParser replaces the SVG,
   so animations restart automatically).
   ============================================ */

/* Header — slides down + fades in */
.lp-h-eyebrow,
.lp-h-title,
.lp-h-meta,
.lp-h-rule {
  opacity: 0;
  animation: lp-head-in 0.3s cubic-bezier(.4,0,.2,1) forwards;
}
.lp-h-eyebrow { animation-delay: 0s;    transform: translateY(-8px); }
.lp-h-title   { animation-delay: 0.04s; transform: translateY(-8px); }
.lp-h-meta    { animation-delay: 0.08s; }
.lp-h-rule    { animation-delay: 0.12s; }
@keyframes lp-head-in {
  to { opacity: 1; transform: translateY(0); }
}

/* Edges — fade in with stagger, then dashes flow forever */
.lp-edge-ribbon {
  opacity: 0;
  animation: lp-ribbon-in 0.3s ease-out forwards;
  animation-delay: inherit;
}
@keyframes lp-ribbon-in { to { opacity: 0.10; } }

.lp-edge-line {
  opacity: 0;
  stroke-dasharray: 8 6;
  animation:
    lp-edge-in 0.3s ease-out forwards,
    lp-edge-flow 1.8s linear infinite 0.3s;
  animation-delay: inherit;
}
@keyframes lp-edge-in   { to { opacity: 0.85; } }
@keyframes lp-edge-flow { to { stroke-dashoffset: -28; } }

.lp-edge-group {
  animation: lp-edge-stage 0.01s linear forwards;  /* gives the group a delay slot */
  animation-delay: inherit;
}
@keyframes lp-edge-stage { to { opacity: 1; } }

/* Mid-curve data dots — scale pop */
.lp-dot-group {
  opacity: 0;
  transform: scale(0);
  transform-origin: center;
  transform-box: fill-box;
  animation: lp-dot-in 0.3s cubic-bezier(.34,1.56,.64,1) forwards;
}
@keyframes lp-dot-in { to { opacity: 1; transform: scale(1); } }

/* Nodes — pop in with bounce, then halo pulses + outer ring rotates forever */
.lp-node {
  opacity: 0;
  /* Opacity-only entrance — keeps positions rock-solid, no bbox-origin drift */
  animation: lp-node-pop 0.3s ease-out forwards;
}
@keyframes lp-node-pop {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.lp-halo {
  transform-origin: center;
  transform-box: fill-box;
  animation: lp-halo-pulse 3.4s ease-in-out infinite;
}
@keyframes lp-halo-pulse {
  0%, 100% { opacity: 0.28; transform: scale(1); }
  50%      { opacity: 0.55; transform: scale(1.08); }
}

.lp-ring-dashed {
  transform-origin: center;
  transform-box: fill-box;
  animation: lp-ring-rotate 16s linear infinite;
}
@keyframes lp-ring-rotate { to { transform: rotate(360deg); } }

/* Footer ticks — fade up in sequence */
.lp-foot {
  opacity: 0;
  transform: translateY(6px);
  transform-origin: center;
  transform-box: fill-box;
  animation: lp-foot-in 0.25s ease-out forwards;
}
@keyframes lp-foot-in { to { opacity: 1; transform: translateY(0); } }

/* Reduced motion — skip the entrance bounces */
@media (prefers-reduced-motion: reduce) {
  .lp-h-eyebrow, .lp-h-title, .lp-h-meta, .lp-h-rule,
  .lp-edge-ribbon, .lp-edge-line, .lp-dot-group,
  .lp-node, .lp-foot {
    animation-duration: 0.001s;
    animation-delay: 0s;
  }
  .lp-halo, .lp-ring-dashed, .lp-edge-line { animation-iteration-count: 1; }
}

/* ============================================
   SPARK — bright glowing segment that traces each edge endlessly
   (the "ray" travelling between courses)
   ============================================ */
.lp-spark {
  /* Tiny 8-px solid stroke + huge gap = one bright dot of light that
     travels along the path like a comet. */
  stroke-dasharray: 8 4000;
  stroke-dashoffset: 0;
  opacity: 0;
  animation:
    lp-spark-in 0.3s ease-out 0.4s forwards,
    lp-spark-fly 2.6s linear infinite 0.8s;
}
@keyframes lp-spark-in  { to { opacity: 1; } }
@keyframes lp-spark-fly { to { stroke-dashoffset: -4008; } }

/* Minimalist single-curve line — DRAWS IN from start to end like a pen
   stroke, then transitions to flowing dashes. Uses a huge dasharray + the
   stroke-dashoffset trick. */
.lp-line {
  opacity: 0.85;
  stroke-dasharray: 6000;
  stroke-dashoffset: 6000;
  animation:
    lp-line-draw 1.0s cubic-bezier(.4,0,.2,1) 0.1s forwards,
    lp-line-flow 3.5s linear infinite 1.2s;
}
@keyframes lp-line-draw {
  to { stroke-dashoffset: 0; }
}
@keyframes lp-line-flow {
  0%   { stroke-dasharray: 6000; stroke-dashoffset: 0; }
  0.1% { stroke-dasharray: 5 7;  stroke-dashoffset: 0; }
  100% { stroke-dasharray: 5 7;  stroke-dashoffset: -120; }
}

.lp-line-glow {
  opacity: 0;
  animation: lp-line-glow-in 1.2s ease-out 0.5s forwards;
}
@keyframes lp-line-glow-in { to { opacity: 0.20; } }

.lp-num, .lp-title, .lp-meta {
  /* text inside the .lp-node group is already animated by .lp-node pop-in */
}

/* ============================================
   ZOOM-LENS — hovering a node magnifies its label card
   ============================================ */
.lp-node {
  cursor: pointer;
}
.lp-hit {
  pointer-events: all;     /* invisible rect that catches hover for the whole node area */
}
.lp-label {
  /* Scale from the geometric centre of the label so the title + meta stay
     visually centred inside the magnified card, not pinned to the top. */
  transform-origin: center;
  transform-box: fill-box;
  transition: transform 0.4s cubic-bezier(.34,1.2,.64,1),
              filter 0.4s ease-out;
}
.lp-label-bg {
  transition: opacity 0.3s ease-out;
}
.lp-title { transition: fill 0.3s; }
.lp-meta  { transition: fill 0.3s; }

.lp-node:hover .lp-label {
  transform: scale(1.25);
  filter: drop-shadow(0 10px 24px rgba(4,20,15,0.55));
}
.lp-node:hover .lp-label-