/*
 * Author: Martin <lmccc.dev@gmail.com>
 * Co-Author: AI Assistant
 * Description: Official site motion — every @keyframes lives here. Each motion shows a real quantity or a
 *              product process, runs only inside a [data-motion] figure while it is in view (site.js adds
 *              .is-live), animates transform / opacity / stroke-dashoffset only, and stops for reduced motion.
 *              官网动效：所有 @keyframes 集中在此。每个动效只表达真实的量或产品流程，只在 [data-motion] 图进入
 *              视口时运行（site.js 加 .is-live），只改 transform / opacity / stroke-dashoffset，减少动效时停止。
 */

/* ============ Nav: reading progress + current section ============ */
.nav-progress {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  bottom: -1px;
  height: 1px;
  background: var(--star);
  transform: scaleX(0);
  transform-origin: left center;
  pointer-events: none;
}

.nav-links a[aria-current="true"] {
  color: var(--text)
}

.nav-links a[aria-current="true"]::after {
  width: 100%
}

/* ============ Hero: target acquisition (runs once on load) ============ */
.reticle .ring {
  stroke-dasharray: 100;
  stroke-dashoffset: 0
}

.reticle .ticks {
  stroke-dasharray: .5 4.5;
  opacity: .35
}

.reticle .cross,
.reticle .lock {
  transform-box: view-box;
  transform-origin: 200px 200px
}

.reticle .lock path {
  fill: none;
  stroke: var(--star);
  stroke-width: 1.2;
  opacity: .9
}

.reticle text {
  fill: var(--text-3);
  font-family: var(--font-mono);
  font-size: var(--site-fs-label);
  letter-spacing: .08em;
  text-anchor: middle;
}

/* One sweep, then it is gone. The settled reticle is the rings, cross and lock. */
.reticle .sweep {
  transform-box: view-box;
  transform-origin: 200px 200px;
  opacity: 0
}

.reticle .sweep line {
  stroke: var(--star);
  stroke-width: 1
}

.reticle.is-live .cross {
  animation: rt-cross 1.1s var(--ease) both
}

.reticle.is-live .ring-outer {
  animation: rt-draw 1.2s var(--ease) both
}

.reticle.is-live .ring-inner {
  animation: rt-draw 1s var(--ease) .25s both
}

.reticle.is-live .ticks {
  animation: rt-fade-ticks .8s linear .6s both
}


.reticle.is-live .lock {
  animation: rt-lock .7s var(--ease) 1s both
}

.reticle.is-live .mark {
  animation: rt-fade .3s linear 1.5s both
}

@keyframes rt-draw {
  from {
    stroke-dashoffset: 100
  }

  to {
    stroke-dashoffset: 0
  }
}

@keyframes rt-fade-ticks {
  from {
    opacity: 0
  }

  to {
    opacity: .35
  }
}

@keyframes rt-fade {
  from {
    opacity: 0
  }

  to {
    opacity: 1
  }
}

@keyframes rt-cross {
  from {
    opacity: 0
  }

  to {
    opacity: 1
  }
}

@keyframes rt-lock {
  from {
    opacity: 0
  }

  to {
    opacity: 1
  }
}

/* The sweep rides with the ring draw, then fades out. No zoom, no leftover line. */
@keyframes rt-sweep {
  0% {
    opacity: 0;
    transform: rotate(-12deg)
  }

  20% {
    opacity: .55
  }

  70% {
    opacity: .55;
    transform: rotate(150deg)
  }

  100% {
    opacity: 0;
    transform: rotate(168deg)
  }
}

/* Text arrives as one reading pass: hidden until in view, then a short overlapping fade. */
@media (prefers-reduced-motion: no-preference) {
  .js [data-motion="enter"]:not(.is-live) .enter-item {
    opacity: 0;
    transform: translateY(4px)
  }

  .js [data-motion="enter"].is-live .enter-item {
    animation: text-in 1.1s var(--ease) both
  }

  .js [data-motion="enter"].is-live .enter-item:nth-child(2) {
    animation-delay: .08s
  }

  .js [data-motion="enter"].is-live .enter-item:nth-child(3) {
    animation-delay: .16s
  }

  .js [data-motion="enter"].is-live .enter-item:nth-child(4) {
    animation-delay: .24s
  }

  .js [data-motion="enter"].is-live .enter-item:nth-child(5) {
    animation-delay: .32s
  }
}

@keyframes text-in {
  from {
    opacity: 0;
    transform: translateY(4px)
  }

  to {
    opacity: 1;
    transform: none
  }
}

.reticle-telemetry {
  margin-top: 6px;
  font-family: var(--font-mono);
  font-size: var(--site-fs-small);
  letter-spacing: .04em;
  color: var(--text-3);
  text-align: center;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ============ Ontology: one record flows world → ontology → employee (6s) ============ */
.onto-stage {
  position: relative
}

.onto-stage::after {
  content: "";
  position: absolute;
  inset: -1px;
  border: 1px solid var(--star);
  border-radius: inherit;
  opacity: 0;
  pointer-events: none;
}

.onto-flow.is-live .onto-stage::after {
  animation: flow-stage 6s linear infinite
}

.onto-flow.is-live .onto-stage:nth-child(3)::after {
  animation-delay: 2s
}

.onto-flow.is-live .onto-stage:nth-child(5)::after {
  animation-delay: 4s
}

.onto-arrow {
  position: relative
}

.onto-arrow::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 6px;
  width: 6px;
  height: 1px;
  background: var(--star);
  opacity: 0;
}

.onto-flow.is-live .onto-arrow::after {
  animation: flow-arrow 6s linear 1.5s infinite
}

.onto-flow.is-live .onto-arrow:nth-child(4)::after {
  animation-delay: 3.5s
}

@keyframes flow-stage {
  0% {
    opacity: 0
  }

  3% {
    opacity: 1
  }

  23% {
    opacity: 1
  }

  26%,
  100% {
    opacity: 0
  }
}

@keyframes flow-arrow {
  0% {
    opacity: 0;
    transform: translateX(0)
  }

  2% {
    opacity: 1
  }

  8% {
    opacity: 1;
    transform: translateX(24px)
  }

  9%,
  100% {
    opacity: 0;
    transform: translateX(24px)
  }
}

/* ============ Headquarters ⇄ workplace: task out, report back (4s) ============ */
.ce-arrow .track {
  position: relative;
  flex: none;
  width: 56px;
  height: 1px;
  background: linear-gradient(90deg, var(--line), var(--star))
}

.ce-arrow.down .track {
  background: linear-gradient(270deg, var(--line), var(--star))
}

.ce-arrow .track::after {
  content: "";
  position: absolute;
  top: -2px;
  left: 0;
  width: 5px;
  height: 5px;
  background: currentColor;
  opacity: 0;
}

.ce-panel.is-live .ce-arrow.up .track::after {
  animation: dispatch-out 4s linear infinite
}

.ce-panel.is-live .ce-arrow.down .track::after {
  animation: dispatch-back 4s linear infinite
}

@keyframes dispatch-out {
  0% {
    opacity: 0;
    transform: translateX(0)
  }

  4% {
    opacity: 1
  }

  40% {
    opacity: 1;
    transform: translateX(51px)
  }

  44%,
  100% {
    opacity: 0;
    transform: translateX(51px)
  }
}

@keyframes dispatch-back {

  0%,
  50% {
    opacity: 0;
    transform: translateX(51px)
  }

  54% {
    opacity: 1
  }

  90% {
    opacity: 1;
    transform: translateX(0)
  }

  94%,
  100% {
    opacity: 0;
    transform: translateX(0)
  }
}

@keyframes dispatch-out-v {
  0% {
    opacity: 0;
    transform: translateY(0)
  }

  4% {
    opacity: 1
  }

  40% {
    opacity: 1;
    transform: translateY(23px)
  }

  44%,
  100% {
    opacity: 0;
    transform: translateY(23px)
  }
}

@keyframes dispatch-back-v {

  0%,
  50% {
    opacity: 0;
    transform: translateY(23px)
  }

  54% {
    opacity: 1
  }

  90% {
    opacity: 1;
    transform: translateY(0)
  }

  94%,
  100% {
    opacity: 0;
    transform: translateY(0)
  }
}

/* ============ Work loop: step sequencer (site.js advances .is-active every 1.6s) ============ */
@media (hover: none) {
  [data-motion="sequencer"] {
    cursor: pointer
  }
}

.loop-step::after {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  right: 0;
  height: 1px;
  background: var(--star);
  transform: scaleX(0);
  transform-origin: left center;
}

.loop-step::before {
  transition: transform .2s linear
}

.loop-steps.is-live .loop-step.is-active::after {
  transform: scaleX(1);
  transition: transform 1.6s linear
}

.loop-steps.is-live .loop-step.is-active::before {
  transform: scaleY(2.2)
}

.loop-step.is-active h4 {
  color: var(--star)
}

.loop-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 8px 20px;
  margin-top: 20px;
  min-height: 1.5em
}

.loop-meta .idx-mono {
  font-size: var(--site-fs-small)
}

.loop-meta .is-paused {
  color: var(--star)
}

/* ============ One-shot builds: evolution track, platform layers ============ */
.evo-track.is-live::before {
  transform-origin: left center;
  animation: evo-draw 1.4s var(--ease) both
}

.evo-track.is-live .evo-node {
  animation: rt-fade 1.15s var(--ease) both
}

.evo-track.is-live .evo-node:nth-child(2) {
  animation-delay: .25s
}

.evo-track.is-live .evo-node:nth-child(3) {
  animation-delay: .5s
}

.layer-stack.is-live .layer {
  animation: rt-fade 1.15s var(--ease) both
}

.layer-stack.is-live .layer:nth-child(2) {
  animation-delay: .2s
}

.layer-stack.is-live .layer:nth-child(1) {
  animation-delay: .4s
}

.journey.is-live .journey-line {
  animation: evo-draw 1.6s var(--ease) both
}

.journey.is-live .journey-list li {
  animation: rt-fade 1.15s var(--ease) both
}

.journey.is-live .journey-list li:nth-child(2) {
  animation-delay: .3s
}

.journey.is-live .journey-list li:nth-child(3) {
  animation-delay: .6s
}

.journey.is-live .journey-list li:nth-child(4) {
  animation-delay: .9s
}

.journey.is-live .journey-list li:nth-child(5) {
  animation-delay: 1.2s
}

@keyframes evo-draw {
  from {
    transform: scaleX(0)
  }

  to {
    transform: scaleX(1)
  }
}

@keyframes draw-y {
  from {
    transform: scaleY(0)
  }

  to {
    transform: scaleY(1)
  }
}

/* ============ Small screens and reduced motion ============ */
@media (max-width: 960px) {
  .nav-progress {
    display: block
  }

  .reticle-telemetry {
    text-align: left
  }
}

@media (orientation: landscape) and (max-height: 520px) {
  .reticle-telemetry {
    text-align: center
  }
}

@media (max-width: 960px) {
  .ce-arrow .track {
    width: 1px;
    height: 28px;
    background: linear-gradient(180deg, var(--line), var(--star))
  }

  .ce-arrow.down .track {
    background: linear-gradient(0deg, var(--line), var(--star))
  }

  .ce-arrow .track::after {
    top: 0;
    left: -2px
  }

  .ce-panel.is-live .ce-arrow.up .track::after {
    animation-name: dispatch-out-v
  }

  .ce-panel.is-live .ce-arrow.down .track::after {
    animation-name: dispatch-back-v
  }

  .evo-track.is-live::before {
    transform-origin: top center;
    animation-name: draw-y
  }
}

@media (max-width: 560px) {

  .journey.is-live .journey-list::before {
    animation: draw-y 1.6s var(--ease) both
  }

  /* The connector is vertical here; the particle has to travel down, not sideways. */
  .onto-flow.is-live .onto-arrow::after {
    top: 0;
    left: 50%;
    width: 1px;
    height: 6px;
    animation-name: flow-arrow-down
  }
}

@keyframes flow-arrow-down {
  0% {
    opacity: 0;
    transform: translate(-50%, 0)
  }

  2% {
    opacity: 1
  }

  8% {
    opacity: 1;
    transform: translate(-50%, 22px)
  }

  9%,
  100% {
    opacity: 0;
    transform: translate(-50%, 22px)
  }
}

@media (prefers-reduced-motion: reduce) {

  [data-motion],
  [data-motion] *,
  [data-motion]::before,
  [data-motion] *::before,
  [data-motion] *::after {
    animation: none !important;
    transition: none !important;
  }
}
