/* ============================================================
   Component · Training Hub (full)
   Large learning-path SVG + module cards + full schedule.
   ============================================================ */

/* Large learning-path visualisation */
.learning-path {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  padding: var(--space-xl);
  margin-block: var(--space-xl);
}
.learning-path__title {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
  margin-bottom: var(--space-md);
}
.learning-path__svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 360px;
  overflow: visible; /* let the flowing node's glow breathe past the frame */
}
/* Text colour/family is authored inline per element (serif titles, mono data,
   white-on-ink labels) — no blanket override here, or it flattens them all. */

/* Module cards */
.modules {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  border-top: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
}
@media (min-width: 768px) { .modules { grid-template-columns: repeat(2, 1fr); } }
@media (min-width: 1200px) { .modules { grid-template-columns: repeat(5, 1fr); } }

.module {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
  padding: var(--space-lg);
  border-right: 1px solid var(--color-border);
  border-bottom: 1px solid var(--color-border);
  background: var(--color-white);
  transition: background var(--duration-fast) var(--ease-out);
  position: relative;
  isolation: isolate;
}
.module:hover { background: var(--color-surface); }
.module::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--color-ink-muted);
  transition: background var(--duration-fast) var(--ease-out),
              height var(--duration-fast) var(--ease-out);
}
.module:hover::before { background: var(--color-accent); height: 4px; }

.module__num {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
}
.module__title {
  font-family: var(--font-display);
  font-size: var(--text-xl);
  line-height: 1.1;
  color: var(--color-ink);
  letter-spacing: -0.015em;
}
.module__meta {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
  margin-top: auto;
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border-light);
}

/* Schedule */
.schedule {
  margin-top: var(--space-xl);
  border-top: 1px solid var(--color-border);
}
.schedule__row {
  display: grid;
  grid-template-columns: 80px 1fr 140px 100px;
  gap: var(--space-md);
  align-items: center;
  padding: var(--space-md);
  border-bottom: 1px solid var(--color-border-light);
  transition: background var(--duration-fast) var(--ease-out);
}
.schedule__row:hover { background: var(--color-surface); }
@media (max-width: 768px) {
  .schedule__row { grid-template-columns: 1fr 1fr; }
  .schedule__cta { grid-column: 1 / -1; }
}

.schedule__date {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  line-height: 1.2;
  color: var(--color-ink);
}
.schedule__date .month {
  display: block;
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
  margin-bottom: 2px;
}
.schedule__module {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-base);
  color: var(--color-ink);
}
.schedule__module .module-meta {
  display: block;
  font-family: var(--font-mono);
  font-weight: 400;
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
  margin-top: 2px;
}
.schedule__seats {
  font-family: var(--font-mono);
  font-size: var(--text-sm);
  color: var(--color-ink);
}
.schedule__seats .status {
  display: block;
  font-size: 10px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
  margin-top: 2px;
}
.schedule__row.is-filling .schedule__seats { color: var(--color-accent); }
.schedule__row.is-open .schedule__seats { color: var(--color-success); }
.schedule__row.is-full .schedule__seats { color: var(--color-ink-muted); text-decoration: line-through; }

.schedule__cta {
  text-align: right;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}
.schedule__cta a {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  color: var(--color-ink);
  border-bottom: 1px solid transparent;
  transition: color var(--duration-fast) var(--ease-out), border-color var(--duration-fast) var(--ease-out);
}
.schedule__cta a:hover { color: var(--color-accent); border-color: var(--color-accent); }
.schedule__cta .arrow { transition: transform var(--duration-fast) var(--ease-out); }
.schedule__cta a:hover .arrow { transform: translateX(4px); }

/* Module card as link */
a.module {
  text-decoration: none;
  color: inherit;
  display: flex;
}
a.module:focus-visible { outline: 2px solid var(--color-accent); outline-offset: 2px; }

/* ============================================================
   Learning-path schematic — the drawing plots itself
   ------------------------------------------------------------
   On reveal, the curriculum reconstructs the way a drafting
   machine plots it: grid first, then Fundamentals, connectors
   fan out toward the specialist tracks, and everything converges
   into the Coordination capstone. Once plotted, a single node
   flows the spine — occluded as it passes through each module —
   so you literally watch progress travel the path.

   Resting state (below) is the finished diagram. It is also what
   reduced-motion and no-JS visitors see: nothing hidden, no motion.
   Timing is carried on inline `--d` (start delay) per element.
   ============================================================ */

/* The flowing node only exists while it moves; hide it at rest so it
   never sits as a stray dot for reduced-motion / no-animation views. */
.lp-node { opacity: 0; }

@media (prefers-reduced-motion: no-preference) {
  /* Hold the plot blank until the card scrolls in, so nothing flashes. */
  .learning-path:not(.is-visible) :is(.lp-grid, .lp-box, .lp-edge, .lp-label, .lp-legend) {
    opacity: 0;
  }

  /* Grid rules, tier labels, legend — a quiet fade-up. */
  .learning-path.is-visible :is(.lp-grid, .lp-label, .lp-legend) {
    animation: lp-fade 520ms var(--ease-out) var(--d, 0ms) both;
  }

  /* Boxes: the outline is drawn, then the fill floods in. */
  .learning-path.is-visible .lp-box {
    stroke-dasharray: var(--perim);
    animation: lp-box-draw 920ms var(--ease-out) var(--d, 0ms) both;
  }

  /* Connectors: the pen draws each line out to its arrowhead. */
  .learning-path.is-visible .lp-edge {
    stroke-dasharray: 1; /* paired with pathLength="1" for uniform draw */
    animation: lp-edge-draw 620ms var(--ease-out) var(--d, 0ms) both;
  }

  /* Signature: the node travels Fundamentals → Coordination along the
     spine; boxes paint over it, so it dips out of sight through a module. */
  .learning-path.is-visible .lp-node {
    offset-path: path('M 180 160 L 780 160');
    offset-rotate: 0deg;
    filter: drop-shadow(0 0 5px rgba(103, 194, 197, 0.9));
    animation: lp-flow 3600ms var(--ease-in-out) var(--flow-delay, 0ms) infinite;
  }
}

@keyframes lp-fade {
  from { opacity: 0; transform: translateY(5px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes lp-box-draw {
  0%   { opacity: 0; stroke-dashoffset: var(--perim); fill-opacity: 0; }
  6%   { opacity: 1; }
  60%  { stroke-dashoffset: 0; fill-opacity: 0; }
  100% { stroke-dashoffset: 0; fill-opacity: 1; }
}
@keyframes lp-edge-draw {
  0%   { opacity: 0; stroke-dashoffset: 1; }
  20%  { opacity: 1; }
  100% { opacity: 1; stroke-dashoffset: 0; }
}
@keyframes lp-flow {
  0%   { offset-distance: 0%;   opacity: 0; }
  10%  { opacity: 1; }
  88%  { opacity: 1; }
  100% { offset-distance: 100%; opacity: 0; }
}

/* ============================================================
   Training page — motion & interactivity
   The same vocabulary as /services/ and the pillar pages: cards
   cascade in, the top stripe draws with the reveal, leader lines
   and accent indices on hover, rows readable as a whole.
   The learning-path schematic above keeps its own plot animation.
   ============================================================ */

/* --- Module cards ---------------------------------------------- */
.module {
  --cad-inset: 8px;
  --cad-len: 12px;
  overflow: hidden;
}
/* .module is a flex container; its children need to clear the
   overlay, which sits at z-index 1 inside the card's isolation. */
.module > *:not(.cad) { position: relative; z-index: 2; }

/* Pointer-tracked wash, fed by --mx/--my from card-cad.js */
.module::after {
  content: '';
  position: absolute;
  inset: 0;
  background: radial-gradient(
    circle at var(--mx, 50%) var(--my, 50%),
    color-mix(in srgb, var(--color-accent) 10%, transparent) 0%,
    transparent 60%
  );
  opacity: 0;
  transition: opacity var(--duration-normal) var(--ease-out);
  pointer-events: none;
  z-index: 0;
}
.module:hover::after { opacity: 1; }

.module__num { transition: color var(--duration-fast) var(--ease-out); }
.module:hover .module__num { color: var(--color-accent); }
.module__title { transition: transform var(--duration-normal) var(--ease-out); }
.module:hover .module__title { transform: translateX(3px); }

/* Staggered entry with the stripe drawing in behind it — scoped to
   .module[data-reveal] so it out-ranks the card's own background
   transition, and the per-card delay rides on --stagger-i. */
.module[data-reveal] {
  opacity: 0;
  transform: translateY(20px);
  transition:
    opacity var(--duration-slow) var(--ease-out) calc(var(--stagger-i, 0) * 80ms),
    transform var(--duration-slow) var(--ease-out) calc(var(--stagger-i, 0) * 80ms),
    background var(--duration-fast) var(--ease-out);
}
.module[data-reveal].is-visible { opacity: 1; transform: translateY(0); }

.module[data-reveal]::before {
  transform: scaleX(0);
  transform-origin: left center;
  transition:
    transform 700ms var(--ease-out) calc(var(--stagger-i, 0) * 80ms + 140ms),
    background var(--duration-fast) var(--ease-out),
    height var(--duration-fast) var(--ease-out);
}
.module[data-reveal].is-visible::before { transform: scaleX(1); }

/* --- Schedule rows --------------------------------------------- */
.schedule__row {
  position: relative;
  --cad-inset: 6px;
  --cad-len: 10px;
  overflow: hidden;
}
.schedule__row > *:not(.cad) { position: relative; z-index: 2; }

/* Leader line, the way a row being read gets marked in the margin */
.schedule__row::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: var(--color-accent);
  transform: scaleY(0);
  transform-origin: center top;
  transition: transform var(--duration-normal) var(--ease-out);
  z-index: 1;
}
.schedule__row:hover::before,
.schedule__row:focus-within::before { transform: scaleY(1); }

.schedule__date,
.schedule__date .month { transition: color var(--duration-fast) var(--ease-out); }
.schedule__row:hover .schedule__date .month { color: var(--color-accent); }

/* The row is clickable via data-card-link; the Book control mirrors
   its own hover so the affordance reads from anywhere in the row. */
.schedule__row:hover .schedule__cta a {
  color: var(--color-accent);
  border-color: var(--color-accent);
}
.schedule__row:hover .schedule__cta .arrow { transform: translateX(4px); }

.schedule__row[data-reveal] {
  opacity: 0;
  transform: translateX(-10px);
  transition:
    opacity var(--duration-slow) var(--ease-out) calc(var(--stagger-i, 0) * 60ms),
    transform var(--duration-slow) var(--ease-out) calc(var(--stagger-i, 0) * 60ms),
    background var(--duration-fast) var(--ease-out);
}
.schedule__row[data-reveal].is-visible { opacity: 1; transform: translateX(0); }

/* A full cohort is not bookable — no leader line, no false affordance. */
.schedule__row.is-full::before { display: none; }
.schedule__row.is-full:hover .schedule__cta a {
  color: var(--color-ink-muted);
  border-color: var(--color-border);
}

@media (prefers-reduced-motion: reduce) {
  .module::after,
  .module__title,
  .schedule__row::before { transition: none; }
  .module[data-reveal],
  .schedule__row[data-reveal] {
    opacity: 1;
    transform: none;
    transition: background var(--duration-fast) var(--ease-out);
  }
  .module[data-reveal]::before {
    transform: none;
    transition:
      background var(--duration-fast) var(--ease-out),
      height var(--duration-fast) var(--ease-out);
  }
}
