/**
 * motion.css · the animated diagrams in js/motion/ (client direction
 * 2026-10-31; design.md §5).
 *
 * Every rule that HIDES something is scoped to `.is-armed:not(.is-playing)`,
 * which only the script adds: a crawler, a no-JS reader, a prerendered page
 * and a reduced-motion visitor (`.is-static`) always see the finished frame.
 * Only transform, opacity and stroke-dashoffset animate. Each sequence is one
 * pass, staggered by --i (≈ 280ms per step), then still; the travelling
 * spores are SMIL, started by the script, so reduced motion never starts them.
 * Colours are tokens only, so both themes and every daypart work unchanged.
 */

.diagram {
  margin: 0;
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--sp-5);
  align-items: center;
  position: relative;
}

.diagram__art svg {
  display: block;
  width: 100%;
  height: auto;
  max-height: 32rem;
  overflow: visible;
}

/* ---- drawing vocabulary ---- */
.dg-ring { fill: none; stroke: var(--line); stroke-width: 1.5; }
.dg-ring--strong { stroke: color-mix(in oklab, var(--accent) 35%, var(--line)); stroke-width: 2; }
.dg-node { fill: var(--surface-1); stroke: var(--line); stroke-width: 1.25; }
.dg-node--accent { stroke: var(--accent); stroke-width: 1.5; }
.dg-tag { fill: var(--surface-0); stroke: var(--line); stroke-width: 1; }
.dg-core { fill: var(--accent-deep); }
.dg-phase { fill: var(--surface-0); stroke: var(--accent); stroke-width: 1.25; stroke-dasharray: 4 3; }
.dg-phase--live { fill: var(--accent-deep); stroke: var(--accent-deep); stroke-dasharray: none; }
.dg-arc { fill: none; stroke: var(--accent); stroke-width: 4; stroke-linecap: round; opacity: 0.85; }
.dg-feed { fill: none; stroke: var(--line); stroke-width: 1.25; stroke-dasharray: 3 4; }
.dg-draw { fill: none; stroke: var(--accent); stroke-width: 2; stroke-linecap: round; }
.dg-draw--line { stroke-width: 2.5; stroke-linejoin: round; }
.dg-arrowhead { fill: var(--accent); }
.dg-threshold { stroke: var(--risk-watch); stroke-width: 1.5; stroke-dasharray: 6 5; }
.dg-cross { fill: var(--risk-watch); stroke: var(--surface-1); stroke-width: 3; }
.dg-spore { fill: var(--accent); }
.dg-spore--small { opacity: 0.85; }

.dg-label {
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 17px;
  fill: var(--ink-0);
}

.dg-label--serif { font-family: var(--font-display); font-weight: 400; font-style: italic; fill: var(--accent); }

.dg-small { font-family: var(--font-body); font-size: 14px; fill: var(--ink-1); }
.dg-small--phase { font-size: 13px; }
.dg-small--strong { font-weight: 700; fill: var(--ink-0); }
.dg-small--on { fill: #f6f4ec; font-weight: 500; }

.dg-mono {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.05em;
  fill: var(--ink-1);
}

.dg-mono--on { fill: #f6f4ec; }
.dg-mono--muted { fill: var(--ink-2); font-size: 10.5px; }
.dg-mono--watch { fill: color-mix(in oklab, var(--risk-watch) 65%, var(--ink-0)); }

/* Before playing, a travelling spore has nowhere to be. */
.dg-spore { opacity: 0; }
.diagram.is-playing .dg-spore { opacity: 1; transition: opacity var(--dur-base) var(--ease-out) 1.6s; }
.diagram.is-static .dg-spore { display: none; }

/* ---- legend ---- */
.diagram__legend {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  gap: var(--sp-3);
}

.diagram__item {
  display: grid;
  grid-template-columns: 2rem minmax(0, 1fr);
  gap: var(--sp-2);
  padding-block-start: var(--sp-3);
  border-block-start: 1px solid var(--line);
}

.diagram__item:first-child { border-block-start: 0; padding-block-start: 0; }

.diagram__num { color: var(--accent); padding-block-start: 3px; }

.diagram__text { display: block; color: var(--ink-1); line-height: 1.55; }
.diagram__text b { color: var(--ink-0); margin-inline-end: 0.4em; }
.diagram__text .aud-chip { margin-inline-end: 0.4em; vertical-align: 2px; }
.diagram__body { display: block; margin-block-start: 2px; }

.diagram__note {
  grid-column: 1 / -1;
  color: var(--ink-2);
  font-size: 0.75rem;
}

.diagram__replay {
  position: absolute;
  inset-block-start: 0;
  inset-inline-start: 0;
  background: none;
  border: 1px solid var(--line);
  border-radius: var(--r-1);
  color: var(--ink-2);
  font-size: 0.6875rem;
  padding: 6px 10px;
  min-height: 2rem;
  cursor: pointer;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
}

.diagram.is-playing:hover .diagram__replay,
.diagram__replay:focus-visible { opacity: 1; }
.diagram.is-static .diagram__replay,
.diagram:not(.is-armed) .diagram__replay { display: none; }

/* ---- ParametricTrigger response cards: gradient + mycelial grain ----
   The SVG twin of the .myco-surface utility (base.css): stops, edge, vein
   opacity and text colour all come from the --myco-* tokens (tokens.css),
   so the cards and the HTML panels share one skin. Text is #f6f4ec
   (--myco-ink); the lightest stop sits under the cards' bottom-right
   corner, and even a vein pixel on it holds AA (worst case 4.6:1 dark,
   above 5.4:1 light, computed 2026-10-31; design.md §4.3). */
.pt-stop-lit { stop-color: var(--myco-lit); }
.pt-stop-mid { stop-color: var(--myco-mid); }
.pt-stop-deep { stop-color: var(--myco-deep); }
.pt-card { fill: url(#pt-card-fill); stroke: var(--myco-edge); }
.pt-card-grain { fill: #000; opacity: var(--myco-vein-opacity); pointer-events: none; }

/* ---- PlatformLoop: labels with room, and the step the spore has reached ----
   Review round 2 (2026-10-31): 16px labels inside r=56 circles leave clear
   padding from the ring. The current step (set by PlatformLoop.js from the
   spore's own clock) tints its circle and its legend row; colour is never
   the only cue, the row also gains an accent rule on its leading edge.
   Reduced motion never starts the spore, so nothing here ever cycles. */
.pl-label { font-size: 16px; }
.dg-node { transition: fill var(--dur-base) var(--ease-out), stroke-width var(--dur-base) var(--ease-out); }
.pl-node.is-current .dg-node { fill: color-mix(in oklab, var(--accent) 18%, var(--surface-1)); stroke-width: 2.5; }

.diagram--platform-loop .diagram__item {
  padding: var(--sp-3);
  margin-inline: calc(-1 * var(--sp-3));
  border-radius: var(--r-1);
  box-shadow: inset 0 0 0 0 var(--accent);
  transition:
    background-color var(--dur-base) var(--ease-out),
    box-shadow var(--dur-base) var(--ease-out);
}
.diagram--platform-loop .diagram__item:first-child { padding-block-start: var(--sp-3); }
.diagram--platform-loop .diagram__item b { transition: color var(--dur-base) var(--ease-out); }
.diagram--platform-loop .diagram__item.is-current {
  background-color: color-mix(in oklab, var(--accent) 11%, transparent);
  box-shadow: inset 3px 0 0 0 var(--accent);
}
.diagram--platform-loop .diagram__item.is-current b { color: color-mix(in oklab, var(--accent) 70%, var(--ink-0)); }

/* ---- the sequence (no-preference only) ---- */
@media (prefers-reduced-motion: no-preference) {
  .diagram.is-armed .dg-step {
    opacity: 0;
    transform: translateY(8px);
    transform-box: fill-box;
  }

  .diagram.is-armed .dg-draw { stroke-dasharray: 1; stroke-dashoffset: 1; }

  .diagram.is-armed .diagram__item { opacity: 0; transform: translateY(10px); }

  .diagram.is-playing .dg-step {
    animation: dg-in var(--dur-base) var(--ease-grow) both;
    animation-delay: calc(var(--i, 0) * 280ms);
  }

  .diagram.is-playing .dg-draw {
    animation: dg-draw 700ms var(--ease-out) both;
    animation-delay: calc(var(--i, 0) * 280ms);
  }

  .diagram.is-playing .dg-step--flash .dg-cross {
    animation: dg-flash 900ms var(--ease-out) 2;
    animation-delay: 1.5s;
    transform-box: fill-box;
    transform-origin: center;
  }

  .diagram.is-playing .diagram__item {
    animation: dg-in var(--dur-base) var(--ease-out) both;
    animation-delay: calc(400ms + var(--i, 0) * 180ms);
  }
}

@keyframes dg-in { to { opacity: 1; transform: none; } }
@keyframes dg-draw { to { stroke-dashoffset: 0; } }
@keyframes dg-flash { 50% { transform: scale(1.6); opacity: 0.6; } }

@media (max-width: 900px) {
  .diagram { grid-template-columns: 1fr; gap: var(--sp-4); }
}
