/* ==========================================================================
   Knowledge network v3 — "When the concepts connect, real understanding
   begins." Loaded only by index.html. Uses the site's existing design
   tokens from styles.css (--blue, --red, --yellow, --ink, --muted, --paper,
   --line, --white, --blue-soft, --shadow, --radius-card) — no new palette.

   Base state (no JS, or prefers-reduced-motion) = the fully-connected
   network at rest with the message panel already visible. JS dims the
   network, choreographs it building itself, fires one activation wave,
   then recedes the network behind the panel and hands back to a quiet
   ambient loop that keeps the network alive behind the message.
   ========================================================================== */

/* Scoped to this section only — deliberately tighter than the site's
   shared .section padding so the whole experience (heading, network,
   message) can sit inside one desktop viewport without scrolling. */
.kn-section { position: relative; padding: clamp(24px, 3.2vw, 42px) 0; }
.kn-section .section-head { margin: 0 auto 12px; }
.kn-section .eyebrow { margin-bottom: 6px; }
.kn-section .section-head p { margin: 8px auto 0; }

.kn-wrap {
  position: relative;
  max-width: 1140px;
  margin: 8px auto 0;
  --kn-ease-entrance: cubic-bezier(0.16, 0.84, 0.32, 1);
  --kn-ease-draw: cubic-bezier(0.16, 1, 0.3, 1);
  --kn-ease-ambient: cubic-bezier(0.37, 0, 0.63, 1);
  --kn-ease-panel: cubic-bezier(0.22, 1, 0.36, 1);
  --kn-ease-text: cubic-bezier(0.4, 0, 0.2, 1);
  --kn-dur-entrance: 550ms;
  --kn-dur-draw: 480ms;
  --kn-dur-ambient: 2600ms;
  --kn-dur-panel: 1100ms;
  --kn-dur-text: 700ms;
}

.kn-network-layer {
  position: relative;
  transform-origin: center;
  transition: opacity 1100ms var(--kn-ease-panel), filter 1100ms var(--kn-ease-panel), transform 1100ms var(--kn-ease-panel);
}
[data-kn-message] .kn-network-layer {
  opacity: .7;
  filter: blur(.6px) saturate(.82) contrast(.97);
  transform: scale(.992);
}

.kn-svg {
  display: block;
  width: 100%;
  height: auto;
  overflow: visible;
}
.kn-svg.kn-mobile { display: none; }

/* ---------- Nodes: primary (main layer) vs secondary (background layer) ---------- */
.kn-node {
  fill: var(--blue);
  stroke: none;
  transition: opacity var(--kn-dur-entrance) var(--kn-ease-entrance),
              transform var(--kn-dur-entrance) var(--kn-ease-entrance),
              stroke var(--dur) var(--ease), stroke-width var(--dur) var(--ease);
  transform-box: fill-box;
  transform-origin: center;
}
.kn-node.kn-secondary { fill: var(--muted); opacity: .75; }

.kn-label {
  font-family: "Inter", -apple-system, sans-serif;
  font-size: 12px;
  font-weight: 700;
  fill: var(--ink);
  paint-order: stroke;
  stroke: var(--paper);
  stroke-width: 3px;
  stroke-linejoin: round;
  transition: opacity var(--kn-dur-entrance) var(--kn-ease-entrance);
}
.kn-label.kn-secondary { font-size: 10px; font-weight: 600; fill: var(--muted); opacity: .8; }

/* ---------- Edges: background (touches a secondary node) vs main ---------- */
.kn-edge {
  fill: none;
  stroke: var(--blue);
  stroke-width: 1.4;
  stroke-linecap: round;
  opacity: .35;
  transition: stroke-dashoffset var(--kn-dur-draw) var(--kn-ease-draw),
              opacity var(--dur) var(--ease), stroke var(--dur) var(--ease), stroke-width var(--dur) var(--ease);
}
.kn-edges-bg .kn-edge { stroke-width: 1.1; }
.kn-edges-bg .kn-edge.is-on { opacity: .32; }
.kn-edges-main .kn-edge.is-on { opacity: .55; stroke-width: 1.7; }
.kn-edges-main .kn-edge[data-reach="long"].is-on { opacity: .62; stroke-width: 1.85; }

/* ==========================================================================
   JS-enhanced states. Everything below only applies once JS adds
   `data-kn-js` to the root — so with JS disabled, none of this runs and
   the section shows the complete resting network, unstyled by act.
   ========================================================================== */

[data-kn-js] .kn-node { opacity: 0; transform: scale(.4); }
[data-kn-js] .kn-label { opacity: 0; }
[data-kn-js] .kn-edge { opacity: 0; }

[data-kn-js] .kn-node.is-on { opacity: 1; transform: scale(1); }
[data-kn-js] .kn-node.is-on.kn-secondary { opacity: .75; }
[data-kn-js] .kn-label.is-on { opacity: 1; }
[data-kn-js] .kn-label.is-on.kn-secondary { opacity: .8; }

/* faint sign of life before a node's real reveal — 20-30% of the network
   is already faintly visible the moment the section enters view */
[data-kn-js] .kn-node.kn-seed-hint { opacity: .16; transform: scale(.7); }

/* ---------- Reaction keyframes — one distinct feel per event type ---------- */
@media (prefers-reduced-motion: no-preference) {
  [data-kn-js] .kn-node.is-pulsing { animation: kn-node-pulse 560ms var(--kn-ease-draw); }
  [data-kn-js] .kn-edge.is-pulsing { animation: kn-edge-pulse 620ms var(--kn-ease-draw); }
  [data-kn-js] .kn-edge.is-reinforced { animation: kn-edge-reinforce 900ms var(--kn-ease-ambient); }
  [data-kn-js] .kn-node.is-signal-hit { animation: kn-signal-hit 620ms var(--kn-ease-draw); }
  [data-kn-js] .kn-node.is-breathing { animation: kn-breathe var(--kn-dur-ambient) var(--kn-ease-ambient); }
  [data-kn-js] .kn-node.is-nudging { animation: kn-nudge 2200ms var(--kn-ease-ambient); }
  [data-kn-js] .kn-node.is-wave { animation: kn-wave-node 520ms var(--kn-ease-entrance); }
  [data-kn-js] .kn-edge.is-wave { animation: kn-wave-edge 520ms var(--kn-ease-entrance); }
  [data-kn-js] .kn-node.is-message-pulse { animation: kn-message-pulse-node 900ms var(--kn-ease-panel); }
  [data-kn-js] .kn-edge.is-message-pulse { animation: kn-message-pulse-edge 900ms var(--kn-ease-panel); }
}
@keyframes kn-node-pulse {
  0% { transform: scale(1); }
  40% { transform: scale(1.55); }
  100% { transform: scale(1); }
}
@keyframes kn-edge-pulse {
  0% { stroke-width: 1.4; }
  45% { stroke-width: 3; }
  100% { stroke-width: 1.7; }
}
@keyframes kn-edge-reinforce {
  0% { opacity: .55; }
  35% { opacity: 1; stroke: var(--yellow); }
  100% { opacity: .55; stroke: var(--blue); }
}
@keyframes kn-signal-hit {
  0% { transform: scale(1); }
  40% { transform: scale(1.08); }
  100% { transform: scale(1); }
}
@keyframes kn-breathe {
  0%, 100% { opacity: 1; }
  50% { opacity: .55; }
}
@keyframes kn-nudge {
  0%, 100% { translate: 0 0; }
  50% { translate: 3px -2px; }
}
@keyframes kn-wave-node {
  0% { transform: scale(1); }
  40% { transform: scale(1.5); }
  100% { transform: scale(1); }
}
@keyframes kn-wave-edge {
  0% { opacity: .55; stroke-width: 1.7; }
  45% { opacity: 1; stroke: var(--yellow); stroke-width: 3; }
  100% { opacity: .55; stroke: var(--blue); stroke-width: 1.7; }
}
.kn-node.is-wave { stroke: var(--yellow); }
@keyframes kn-message-pulse-node {
  0% { transform: scale(1); stroke-width: 0; }
  40% { transform: scale(1.4); stroke: var(--red); stroke-width: 3; }
  100% { transform: scale(1); stroke-width: 0; }
}
@keyframes kn-message-pulse-edge {
  0% { opacity: .55; stroke-width: 1.7; }
  40% { opacity: 1; stroke: var(--red); stroke-width: 2.6; }
  100% { opacity: .55; stroke: var(--blue); stroke-width: 1.7; }
}

/* signal-carrying edges brighten in gold/red while a signal rides them */
.kn-edge.is-on.kn-carrying { stroke: var(--yellow); opacity: .7; }

/* one subtle expanding ring from the network's centre, timed with the
   activation wave — reinforces "one idea activates many others" */
.kn-ripple {
  fill: none;
  stroke: var(--yellow);
  stroke-width: 1.4;
  opacity: 0;
  r: 6;
}
@media (prefers-reduced-motion: no-preference) {
  .kn-ripple.is-on { animation: kn-ripple-out 1000ms var(--kn-ease-entrance); }
}
@keyframes kn-ripple-out {
  0% { r: 6; opacity: .6; }
  100% { r: 260; opacity: 0; }
}

/* ---------- Signals: travelling points of light, above everything ---------- */
.kn-signals { pointer-events: none; }
.kn-signal {
  fill: var(--yellow-soft, #FFF6DC);
  opacity: 0;
  filter: drop-shadow(0 0 3px rgba(255, 199, 44, .85));
}
.kn-signal.is-on { opacity: 1; }
.kn-signal.kn-signal-active { fill: var(--red); filter: drop-shadow(0 0 3px rgba(216, 31, 42, .7)); }
.kn-signal.kn-signal-wave { fill: var(--yellow); filter: drop-shadow(0 0 4px rgba(255, 199, 44, .9)); }
.kn-signal.kn-signal-ambient { fill: var(--yellow); filter: drop-shadow(0 0 2px rgba(255, 199, 44, .55)); }

/* ---------- Message panel — the climax of the sequence ---------- */
.kn-message {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: min(620px, 56%);
  text-align: center;
  background: rgba(250, 247, 241, .88);
  border: 1px solid rgba(216, 210, 196, .5);
  border-radius: var(--radius-card, 20px);
  box-shadow: 0 30px 70px rgba(15, 27, 45, .16), 0 10px 24px rgba(15, 27, 45, .08);
  padding: 40px 46px;
  backdrop-filter: blur(6px) saturate(.9);
  -webkit-backdrop-filter: blur(6px) saturate(.9);
  transition: opacity var(--kn-dur-panel) var(--kn-ease-panel), transform var(--kn-dur-panel) var(--kn-ease-panel);
  pointer-events: none;
}
[data-kn-js] .kn-message {
  opacity: 0;
  transform: translate(-50%, calc(-50% + 10px)) scale(.985);
}
.kn-message.is-on {
  opacity: 1;
  transform: translate(-50%, -50%) scale(1);
}
.kn-message-eyebrow {
  margin: 0 0 12px;
  font-size: .8rem;
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: .12em;
  color: var(--red);
}
.kn-message-heading {
  margin: 0;
  font-family: "Outfit", "Inter", -apple-system, sans-serif;
  font-size: clamp(2.3rem, 4vw, 3.4rem);
  font-weight: 800;
  line-height: 1.08;
  letter-spacing: -0.01em;
  color: var(--ink);
  transition: opacity var(--kn-dur-text) var(--kn-ease-text), transform var(--kn-dur-text) var(--kn-ease-text);
}
[data-kn-js] .kn-message-heading { opacity: 0; transform: translateY(6px); }
.kn-message-heading.is-on { opacity: 1; transform: none; }

/* the payoff word arrives a beat after the rest of the sentence */
.kn-message-highlight {
  color: var(--red);
  transition: opacity var(--kn-dur-text) var(--kn-ease-text) 140ms, transform var(--kn-dur-text) var(--kn-ease-text) 140ms;
}
[data-kn-js] .kn-message-highlight { opacity: 0; transform: translateY(4px); display: inline-block; }
.kn-message-heading.is-on .kn-message-highlight { opacity: 1; transform: none; }

/* ---------- Replay: a small, understated icon — not a labelled control ---------- */
.kn-replay {
  position: absolute;
  right: 6px;
  bottom: 2px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  padding: 0;
  border-radius: 50%;
  border: 1px solid var(--line);
  background: var(--white);
  color: var(--muted);
  opacity: .55;
  cursor: pointer;
  transition: opacity var(--dur) var(--ease), color var(--dur) var(--ease), border-color var(--dur) var(--ease);
}
.kn-replay:hover, .kn-replay:focus-visible { opacity: 1; color: var(--blue); border-color: var(--blue); }
.kn-replay[hidden] { display: none; }
.kn-replay svg { width: 14px; height: 14px; }

/* ---------- Hover interaction (hover-capable pointers, after the message appears) ---------- */
@media (hover: hover) and (pointer: fine) {
  [data-kn-js][data-kn-idle] .kn-node { cursor: pointer; }
  [data-kn-js][data-kn-idle][data-kn-hover] .kn-edge.is-on:not(.kn-related) { opacity: .12; }
  [data-kn-js][data-kn-idle][data-kn-hover] .kn-node.is-on:not(.kn-related) { opacity: .32; }
  [data-kn-js][data-kn-idle][data-kn-hover] .kn-label.is-on:not(.kn-related) { opacity: .2; }
  .kn-node.kn-related { opacity: 1 !important; transform: scale(1.2); }
  .kn-label.kn-related { opacity: 1 !important; }
  .kn-edge.kn-related { opacity: 1 !important; stroke: var(--yellow); }
}

/* ---------- Accessible summary (real DOM copy, not the aria-hidden visual) ---------- */
.kn-a11y-summary { position: absolute; left: -9999px; top: auto; width: 1px; height: 1px; overflow: hidden; }

/* ---------- Reduced motion: fully assembled network, message already visible ---------- */
@media (prefers-reduced-motion: reduce) {
  [data-kn-js] .kn-node,
  [data-kn-js] .kn-label,
  [data-kn-js] .kn-edge { opacity: unset !important; transform: none !important; }
  .kn-network-layer { opacity: .7; filter: blur(.6px) saturate(.82) contrast(.97) !important; transform: none !important; }
  .kn-message { opacity: 1 !important; transform: translate(-50%, -50%) !important; }
  .kn-message-heading { opacity: 1 !important; transform: none !important; }
  .kn-message-highlight { opacity: 1 !important; transform: none !important; }
  .kn-signal { display: none; }
  .kn-replay { display: none; }
}
/* the no-blur-on-mobile decision must hold under reduced motion too —
   without this, the rule above would quietly reapply desktop's blur */
@media (prefers-reduced-motion: reduce) and (max-width: 720px) {
  .kn-network-layer { opacity: .76 !important; filter: saturate(.85) contrast(.96) !important; }
}

/* ---------- Responsive ---------- */
@media (max-width: 720px) {
  .kn-section { padding: 12px 0; }
  .kn-section .section-head { margin-bottom: 4px; }
  /* scoped to this section only — the shared heading/paragraph styles
     stay untouched everywhere else on the site. A modest reduction
     (not "tiny" text) so the whole section, not just the network, can
     be taken in as one unit on a phone screen. */
  .kn-section h2 { font-size: 1.5rem; line-height: 1.12; }
  .kn-section .section-head p { font-size: .95rem; line-height: 1.32; }
  .kn-svg.kn-desktop { display: none; }
  .kn-svg.kn-mobile { display: block; }
  .kn-wrap {
    max-width: 380px; margin-top: 0;
    /* Faster reveal/panel/text transitions to match the quicker JS
       build schedule on mobile (see knowledge-network.js T_* constants) —
       desktop's timings are untouched. */
    --kn-dur-entrance: 400ms;
    --kn-dur-panel: 800ms;
    --kn-dur-text: 500ms;
  }
  /* more compact, leaves visible network on all sides rather than
     covering most of the (now much shorter) mobile network */
  .kn-message { width: min(280px, 80%); padding: 18px 16px; }
  .kn-message-heading { font-size: clamp(1.6rem, 7.4vw, 2.2rem); }
  [data-kn-message] .kn-network-layer { opacity: .76; filter: saturate(.85) contrast(.96); }
}
