/* gravity-notes.css — the two dither "gravity" diagrams on gravity.html.
   Field grammar: void panel, hairlines, IBM Plex Mono labels, tokenized colour.
   Chroma is deliberate: Lab pink on the valley caption; notes accent orange
   on the escape vector. Linked from gravity.html only. */

.grav-field {
  margin: 4px 0 44px;
  padding: clamp(10px, 2.4vw, 22px);
  background: var(--void);
  overflow: hidden;
}
.grav-svg {
  display: block;
  width: 100%;
  height: auto;
}

/* ---- warped mesh under-layer (subtle spacetime well) ---- */
.gm-mesh-layer { opacity: 0.5; }
.gm-mesh {
  fill: none;
  stroke: var(--hairline);
  stroke-width: 1;
}

/* ---- dither field ---- */
.gm-dot { fill: var(--faint); }
.gm-dot--near { fill: var(--dim); }
.gv-dot { fill: var(--page-insights); opacity: 0.85; }

/* Valley / escape: drop the grey dither — mesh + chips (and escape's you-cluster) carry the idea */
.grav-field--valley .gm-field,
.grav-field--escape .gm-dot {
  display: none;
}

.grav-field--valley .gm-mesh-layer,
.grav-field--escape .gm-mesh-layer {
  opacity: 0.65;
  transform-origin: 50% 48%;
  transform-box: fill-box;
}

/* samples + rails: LLM decisions falling into the mass */
.gm-rail {
  fill: none;
  stroke: var(--page-lab);
  stroke-width: 1.25;
  stroke-dasharray: 3 7;
  opacity: 0.4;
}
.gm-pull-dot {
  fill: var(--page-lab);
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
}
.gm-mass-label {
  font-family: var(--page-title);
  font-size: 28px;
  font-weight: 600;
  fill: var(--page-lab);
  letter-spacing: 0.04em;
  opacity: 0.9;
}

/* ---- cliché chips ---- */
.gm-chip-bg { fill: var(--panel); stroke: var(--border); stroke-width: 1; }
.gm-chip-ln { fill: none; stroke: var(--faint); stroke-width: 1; }
.gm-chip-ln2 { fill: var(--void); stroke: var(--border); stroke-width: 1; }
.gm-chip-fill { fill: var(--faint); stroke: none; }

/* ---- ignored edge specimens ---- */
.gm-edge { opacity: 0.36; }
.gm-edge-box { fill: none; stroke: var(--border); stroke-width: 1; stroke-dasharray: 3 3; }
.gm-edge-ln { fill: none; stroke: var(--faint); stroke-width: 1; }
.gm-edge-fill { fill: var(--faint); stroke: none; }
.gm-tag {
  font-family: var(--font-mono);
  font-size: 14px;
  fill: var(--faint);
  letter-spacing: 0.02em;
}

/* ---- in-field caption ---- */
.gm-cap {
  font-family: var(--font-mono);
  font-size: 21px;
  fill: var(--dim);
  letter-spacing: 0.01em;
}

.grav-field--escape .gm-cap {
  fill: var(--page-insights);
}

/* ---- escape path (mirror of valley gravity, Taste-orange, toward "you") ---- */
.gv-rail {
  fill: none;
  stroke: var(--page-insights);
  stroke-width: 1.25;
  stroke-dasharray: 3 7;
  opacity: 0.55;
}
.gv-tick-mark { stroke: var(--page-insights); stroke-width: 2; opacity: 0.8; }
.gv-tick {
  font-family: var(--font-mono);
  font-size: 16px;
  fill: var(--dim);
  letter-spacing: 0.02em;
}
.gv-you-label {
  font-family: var(--page-title);
  font-size: 36px;
  font-weight: 600;
  fill: var(--page-insights);
  stroke: var(--void);
  stroke-width: 10px;
  paint-order: stroke fill;
  text-anchor: middle;
  letter-spacing: 0.04em;
  opacity: 1;
}
.gv-travel {
  fill: var(--page-insights);
  opacity: 0;
  transform-box: fill-box;
  transform-origin: center;
}

/* ---- under-panel note (escape) ---- */
.grav-note {
  font-family: var(--font-mono);
  font-size: 12.5px;
  color: var(--dim);
  margin: -32px 0 48px;
  letter-spacing: 0.01em;
}
.grav-note b { color: var(--page-insights); font-weight: 500; }

/* At small widths the in-field labels would render sub-pixel — hide them and
   lean on the aria-label. The graphics (mesh, dither, chips, vector) still
   scale and read. */
@media (max-width: 640px) {
  .gm-cap, .gm-tag, .gv-tick { display: none; }
  .grav-field--escape .gm-cap {
    display: block;
    font-size: 16px;
  }
  .gv-you-label { font-size: 42px; }
  .gm-mass-label { font-size: 22px; }
}

/* ---- motion: gated on .labm (page adds it only when reduced-motion is off) ---- */
.labm .gm-shimmer { animation: gm-shim 5.2s ease-in-out infinite; }
.labm .gm-shimmer--1 { animation-delay: 0.6s; }
.labm .gm-shimmer--2 { animation-delay: 1.3s; }
.labm .gm-shimmer--3 { animation-delay: 2.0s; }
.labm .gm-shimmer--4 { animation-delay: 2.8s; }
.labm .gm-shimmer--5 { animation-delay: 3.6s; }
@keyframes gm-shim {
  0%, 100% { opacity: 0.35; }
  50% { opacity: 0.95; }
}

/* Valley: mesh breathes inward (the well) */
.labm .grav-field--valley .gm-mesh-layer {
  animation: gm-well 7.5s ease-in-out infinite;
}
@keyframes gm-well {
  0%, 100% { transform: scale(1); opacity: 0.55; }
  50% { transform: scale(0.972); opacity: 0.78; }
}

/* Escape: "you" peak breathes; valley label stays shared */
.labm .grav-field--escape .gv-you-label {
  animation: gv-you-label 5.5s ease-in-out infinite;
}
.labm .grav-field--escape .gv-dot {
  animation: gv-you-dot 5.5s ease-in-out infinite;
}
@keyframes gv-you-label {
  0%, 100% { opacity: 0.92; }
  50% { opacity: 1; }
}
@keyframes gv-you-dot {
  0%, 100% { opacity: 0.7; }
  50% { opacity: 1; }
}

/* Valley: samples accelerate into the pile along gravity rails */
.labm .gm-rail {
  animation: gm-rail-flow 2.4s linear infinite;
}
@keyframes gm-rail-flow {
  to { stroke-dashoffset: -40; }
}

.labm .gm-pull-dot {
  animation: gm-pull 3.6s cubic-bezier(0.55, 0.05, 0.92, 0.3) infinite;
}
.labm .gm-pull--1 { animation-delay: 0.3s; }
.labm .gm-pull--2 { animation-delay: 0.6s; }
.labm .gm-pull--3 { animation-delay: 0.9s; }
.labm .gm-pull--4 { animation-delay: 1.2s; }
.labm .gm-pull--5 { animation-delay: 1.5s; }
.labm .gm-pull--6 { animation-delay: 1.8s; }
.labm .gm-pull--7 { animation-delay: 2.1s; }
.labm .gm-pull--8 { animation-delay: 2.4s; }
.labm .gm-pull--9 { animation-delay: 2.7s; }
.labm .gm-pull--10 { animation-delay: 3.0s; }
.labm .gm-pull--11 { animation-delay: 3.3s; }
@keyframes gm-pull {
  0% { transform: translate(0, 0) scale(1); opacity: 0; }
  8% { opacity: 0.95; }
  70% { opacity: 0.95; }
  100% { transform: translate(var(--tx), var(--ty)) scale(0.35); opacity: 0; }
}

.labm .gm-mass-label {
  animation: gm-mass-pulse 3.6s ease-in-out infinite;
}
@keyframes gm-mass-pulse {
  0%, 100% { opacity: 0.7; }
  50% { opacity: 1; }
}

/* soft settle on the cliché pile as mass arrives (valley only) */
.labm .grav-field--valley .gm-pile {
  transform-origin: 560px 310px;
  transform-box: view-box;
  animation: gm-pile-settle 7.5s ease-in-out infinite;
}
@keyframes gm-pile-settle {
  0%, 100% { transform: scale(1); }
  50% { transform: scale(1.022); }
}

/* Escape: rails flow + samples leave the valley toward "you" */
.labm .gv-rail {
  animation: gm-rail-flow 2.4s linear infinite;
}
.labm .gv-travel {
  animation: gv-travel 3.6s cubic-bezier(0.15, 0.55, 0.35, 1) infinite;
}
.labm .gv-travel--1 { animation-delay: 0.3s; }
.labm .gv-travel--2 { animation-delay: 0.6s; }
.labm .gv-travel--3 { animation-delay: 0.9s; }
.labm .gv-travel--4 { animation-delay: 1.2s; }
.labm .gv-travel--5 { animation-delay: 1.5s; }
.labm .gv-travel--6 { animation-delay: 1.8s; }
.labm .gv-travel--7 { animation-delay: 2.1s; }
.labm .gv-travel--8 { animation-delay: 2.4s; }
.labm .gv-travel--9 { animation-delay: 2.7s; }
.labm .gv-travel--10 { animation-delay: 3.0s; }
.labm .gv-travel--11 { animation-delay: 3.3s; }
@keyframes gv-travel {
  0% { transform: translate(0, 0) scale(1); opacity: 0; }
  8% { opacity: 0.95; }
  55% { opacity: 0.9; }
  100% { transform: translate(var(--tx), var(--ty)) scale(0.4); opacity: 0; }
}

@media (prefers-reduced-motion: reduce) {
  .gm-shimmer,
  .gv-travel,
  .gm-pull-dot,
  .gm-rail,
  .gv-rail,
  .gm-mass-label,
  .grav-field--valley .gm-mesh-layer,
  .grav-field--valley .gm-pile,
  .grav-field--escape .gv-you-label,
  .grav-field--escape .gv-dot {
    animation: none !important;
  }
  .gv-travel,
  .gm-pull-dot {
    opacity: 0;
  }
  .gm-rail,
  .gv-rail {
    opacity: 0.35;
  }
  .gm-mass-label {
    opacity: 0.9;
  }
  .gv-you-label {
    opacity: 1;
  }
}
